rustfmt code

This commit is contained in:
Drakulix 2017-12-15 18:38:10 +01:00
parent b0d4bdc36d
commit 4207611e6d
21 changed files with 648 additions and 500 deletions

View File

@ -60,7 +60,6 @@ rental! {
}
use self::graphics::{Graphics, Surface};
/// Backend based on a `DrmDevice` and a given crtc
pub struct DrmBackend {
graphics: Graphics,
@ -71,9 +70,10 @@ pub struct DrmBackend {
}
impl DrmBackend {
pub(crate) fn new(context: Rc<devices::Context>, crtc: crtc::Handle, mode: Mode,
connectors: Vec<connector::Handle>, logger: ::slog::Logger)
-> Result<DrmBackend> {
pub(crate) fn new(
context: Rc<devices::Context>, crtc: crtc::Handle, mode: Mode, connectors: Vec<connector::Handle>,
logger: ::slog::Logger,
) -> Result<DrmBackend> {
// logger already initialized by the DrmDevice
let log = ::slog_or_stdlog(logger);
info!(log, "Initializing DrmBackend");
@ -145,9 +145,7 @@ impl DrmBackend {
&connectors,
(0, 0),
Some(mode),
).chain_err(
|| ErrorKind::DrmDev(format!("{:?}", context.devices.drm)),
)?;
).chain_err(|| ErrorKind::DrmDev(format!("{:?}", context.devices.drm)))?;
front_bo.set_userdata(fb);
Ok(EGL {
@ -193,9 +191,7 @@ impl DrmBackend {
/// Errors if the new connector does not support the currently set `Mode`
pub fn add_connector(&mut self, connector: connector::Handle) -> Result<()> {
let info = connector::Info::load_from_device(self.graphics.head().head().head(), connector)
.chain_err(|| {
ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head()))
})?;
.chain_err(|| ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head())))?;
// check if the connector can handle the current mode
if info.modes().contains(&self.mode) {
@ -203,9 +199,8 @@ impl DrmBackend {
let encoders = info.encoders()
.iter()
.map(|encoder| {
encoder::Info::load_from_device(self.graphics.head().head().head(), *encoder).chain_err(
|| ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head())),
)
encoder::Info::load_from_device(self.graphics.head().head().head(), *encoder)
.chain_err(|| ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head())))
})
.collect::<Result<Vec<encoder::Info>>>()?;
@ -215,9 +210,7 @@ impl DrmBackend {
.head()
.head()
.resource_handles()
.chain_err(|| {
ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head()))
})?;
.chain_err(|| ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head())))?;
if !encoders
.iter()
.map(|encoder| encoder.possible_crtcs())
@ -272,9 +265,7 @@ impl DrmBackend {
// check the connectors
for connector in &self.connectors {
if !connector::Info::load_from_device(self.graphics.head().head().head(), *connector)
.chain_err(|| {
ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head()))
})?
.chain_err(|| ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head())))?
.modes()
.contains(&mode)
{
@ -295,9 +286,7 @@ impl DrmBackend {
// resolution.
debug!(
logger_ref,
"Reinitializing surface for new mode: {}:{}",
w,
h
"Reinitializing surface for new mode: {}:{}", w, h
);
graphics.gbm.surface = Surface::try_new(
{
@ -340,9 +329,8 @@ impl DrmBackend {
front_bo.format()
);
// we need a framebuffer per front_buffer
let fb = framebuffer::create(graphics.context.devices.drm, &*front_bo).chain_err(|| {
ErrorKind::DrmDev(format!("{:?}", graphics.context.devices.drm))
})?;
let fb = framebuffer::create(graphics.context.devices.drm, &*front_bo)
.chain_err(|| ErrorKind::DrmDev(format!("{:?}", graphics.context.devices.drm)))?;
debug!(logger_ref, "Initialize screen");
crtc::set(
@ -352,9 +340,7 @@ impl DrmBackend {
connectors_ref,
(0, 0),
Some(mode),
).chain_err(|| {
ErrorKind::DrmDev(format!("{:?}", graphics.context.devices.drm))
})?;
).chain_err(|| ErrorKind::DrmDev(format!("{:?}", graphics.context.devices.drm)))?;
front_bo.set_userdata(fb);
Ok(EGL {
@ -424,13 +410,12 @@ impl GraphicsBackend for DrmBackend {
self.graphics.head().head().head(),
self.crtc,
(x as i32, y as i32),
).chain_err(|| {
ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head()))
})
).chain_err(|| ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head())))
}
fn set_cursor_representation(&self, buffer: &ImageBuffer<Rgba<u8>, Vec<u8>>, hotspot: (u32, u32))
-> Result<()> {
fn set_cursor_representation(
&self, buffer: &ImageBuffer<Rgba<u8>, Vec<u8>>, hotspot: (u32, u32)
) -> Result<()> {
let (w, h) = buffer.dimensions();
debug!(self.logger, "Importing cursor");
@ -463,9 +448,9 @@ impl GraphicsBackend for DrmBackend {
(hotspot.0 as i32, hotspot.1 as i32),
).is_err()
{
crtc::set_cursor(self.graphics.head().head().head(), self.crtc, &cursor).chain_err(|| {
ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head()))
})?;
crtc::set_cursor(self.graphics.head().head().head(), self.crtc, &cursor).chain_err(
|| ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head())),
)?;
}
// and store it
@ -498,7 +483,10 @@ impl EGLGraphicsBackend for DrmBackend {
// would most likely result in a lot of flickering.
// neither weston, wlc or wlroots bother with that as well.
// so we just assume we got at least two buffers to do flipping
let mut next_bo = surface.gbm.lock_front_buffer().expect("Surface only has one front buffer. Not supported by smithay");
let mut next_bo = surface
.gbm
.lock_front_buffer()
.expect("Surface only has one front buffer. Not supported by smithay");
// create a framebuffer if the front buffer does not have one already
// (they are reused by gbm)
@ -506,7 +494,8 @@ impl EGLGraphicsBackend for DrmBackend {
let fb = if let Some(info) = maybe_fb {
info
} else {
let fb = framebuffer::create(graphics.context.devices.drm, &*next_bo).map_err(|_| SwapBuffersError::ContextLost)?;
let fb = framebuffer::create(graphics.context.devices.drm, &*next_bo)
.map_err(|_| SwapBuffersError::ContextLost)?;
next_bo.set_userdata(fb);
fb
};
@ -515,7 +504,12 @@ impl EGLGraphicsBackend for DrmBackend {
trace!(self.logger, "Queueing Page flip");
// and flip
crtc::page_flip(graphics.context.devices.drm, self.crtc, fb.handle(), &[crtc::PageFlipFlags::PageFlipEvent]).map_err(|_| SwapBuffersError::ContextLost)
crtc::page_flip(
graphics.context.devices.drm,
self.crtc,
fb.handle(),
&[crtc::PageFlipFlags::PageFlipEvent],
).map_err(|_| SwapBuffersError::ContextLost)
})
})
}
@ -532,7 +526,9 @@ impl EGLGraphicsBackend for DrmBackend {
}
fn is_current(&self) -> bool {
self.graphics.rent_all(|graphics| graphics.context.egl.is_current() && graphics.gbm.surface.rent(|egl| egl.surface.is_current()))
self.graphics.rent_all(|graphics| {
graphics.context.egl.is_current() && graphics.gbm.surface.rent(|egl| egl.surface.is_current())
})
}
unsafe fn make_current(&self) -> ::std::result::Result<(), SwapBuffersError> {

View File

@ -188,9 +188,9 @@
//! ```
use backend::graphics::egl::{EGLContext, GlAttributes, PixelFormatRequirements};
use backend::graphics::egl::EGLGraphicsBackend;
#[cfg(feature = "backend_session")]
use backend::session::SessionObserver;
use backend::graphics::egl::EGLGraphicsBackend;
use drm::Device as BasicDevice;
use drm::control::{connector, crtc, encoder, Mode, ResourceInfo};
use drm::control::Device as ControlDevice;
@ -204,11 +204,11 @@ use std::collections::HashMap;
use std::fs::File;
use std::hash::{Hash, Hasher};
use std::io::Result as IoResult;
use std::os::unix::io::{IntoRawFd, AsRawFd, RawFd};
use std::rc::Rc;
use std::mem;
use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
use std::rc::Rc;
use std::time::Duration;
use wayland_server::{EventLoopHandle, StateToken, StateProxy};
use wayland_server::{EventLoopHandle, StateProxy, StateToken};
use wayland_server::sources::{FdEventSource, FdEventSourceImpl, FdInterest};
mod backend;
@ -369,25 +369,21 @@ impl<B: From<DrmBackend> + Borrow<DrmBackend> + 'static> DrmDevice<B> {
let mut old_state = HashMap::new();
let res_handles = drm.resource_handles()
.chain_err(|| {
ErrorKind::DrmDev(format!("Loading drm resources on {:?}", drm))
})?;
.chain_err(|| ErrorKind::DrmDev(format!("Loading drm resources on {:?}", drm)))?;
for &con in res_handles.connectors() {
let con_info = connector::Info::load_from_device(&drm, con)
.chain_err(|| {
ErrorKind::DrmDev(format!("Loading connector info on {:?}", drm))
})?;
.chain_err(|| ErrorKind::DrmDev(format!("Loading connector info on {:?}", drm)))?;
if let Some(enc) = con_info.current_encoder() {
let enc_info = encoder::Info::load_from_device(&drm, enc)
.chain_err(|| {
ErrorKind::DrmDev(format!("Loading encoder info on {:?}", drm))
})?;
.chain_err(|| ErrorKind::DrmDev(format!("Loading encoder info on {:?}", drm)))?;
if let Some(crtc) = enc_info.current_crtc() {
let info = crtc::Info::load_from_device(&drm, crtc)
.chain_err(|| {
ErrorKind::DrmDev(format!("Loading crtc info on {:?}", drm))
})?;
old_state.entry(crtc).or_insert((info, Vec::new())).1.push(con);
.chain_err(|| ErrorKind::DrmDev(format!("Loading crtc info on {:?}", drm)))?;
old_state
.entry(crtc)
.or_insert((info, Vec::new()))
.1
.push(con);
}
}
}
@ -426,8 +422,9 @@ impl<B: From<DrmBackend> + Borrow<DrmBackend> + 'static> DrmDevice<B> {
///
/// Errors if initialization fails or the mode is not available on all given
/// connectors.
pub fn create_backend<'a, I, S>(&mut self, state: S, crtc: crtc::Handle, mode: Mode, connectors: I)
-> Result<&StateToken<B>>
pub fn create_backend<'a, I, S>(
&mut self, state: S, crtc: crtc::Handle, mode: Mode, connectors: I
) -> Result<&StateToken<B>>
where
I: Into<Vec<connector::Handle>>,
S: Into<StateProxy<'a>>,
@ -447,7 +444,10 @@ impl<B: From<DrmBackend> + Borrow<DrmBackend> + 'static> DrmDevice<B> {
for connector in &connectors {
let con_info = connector::Info::load_from_device(self.context.head().head(), *connector)
.chain_err(|| {
ErrorKind::DrmDev(format!("Loading connector info on {:?}", self.context.head().head()))
ErrorKind::DrmDev(format!(
"Loading connector info on {:?}",
self.context.head().head()
))
})?;
// check the mode
@ -461,21 +461,26 @@ impl<B: From<DrmBackend> + Borrow<DrmBackend> + 'static> DrmDevice<B> {
.iter()
.map(|encoder| {
encoder::Info::load_from_device(self.context.head().head(), *encoder).chain_err(|| {
ErrorKind::DrmDev(format!("Loading encoder info on {:?}", self.context.head().head()))
ErrorKind::DrmDev(format!(
"Loading encoder info on {:?}",
self.context.head().head()
))
})
})
.collect::<Result<Vec<encoder::Info>>>()?;
// and if any encoder supports the selected crtc
let resource_handles = self.resource_handles().chain_err(|| {
ErrorKind::DrmDev(format!("Loading drm resources on {:?}", self.context.head().head()))
ErrorKind::DrmDev(format!(
"Loading drm resources on {:?}",
self.context.head().head()
))
})?;
if !encoders
.iter()
.map(|encoder| encoder.possible_crtcs())
.any(|crtc_list| {
resource_handles.filter_crtcs(crtc_list).contains(&crtc)
}) {
.any(|crtc_list| resource_handles.filter_crtcs(crtc_list).contains(&crtc))
{
bail!(ErrorKind::NoSuitableEncoder(con_info, crtc))
}
}
@ -484,7 +489,8 @@ impl<B: From<DrmBackend> + Borrow<DrmBackend> + 'static> DrmDevice<B> {
let logger = self.logger.new(o!("crtc" => format!("{:?}", crtc)));
let backend = DrmBackend::new(self.context.clone(), crtc, mode, connectors, logger)?;
self.backends.insert(crtc, state.into().insert(backend.into()));
self.backends
.insert(crtc, state.into().insert(backend.into()));
Ok(self.backends.get(&crtc).unwrap())
}
@ -505,7 +511,7 @@ impl<B: From<DrmBackend> + Borrow<DrmBackend> + 'static> DrmDevice<B> {
/// Panics if the backend is already borrowed from the state
pub fn destroy_backend<'a, S>(&mut self, state: S, crtc: &crtc::Handle)
where
S: Into<StateProxy<'a>>
S: Into<StateProxy<'a>>,
{
if let Some(token) = self.backends.remove(crtc) {
state.into().remove(token);
@ -540,12 +546,25 @@ impl<B: Borrow<DrmBackend> + 'static> Drop for DrmDevice<B> {
panic!("Pending DrmBackends. Please free all backends before the DrmDevice gets destroyed");
}
for (handle, (info, connectors)) in self.old_state.drain() {
if let Err(err) = crtc::set(self.context.head().head(), handle, info.fb(), &connectors, info.position(), info.mode()) {
error!(self.logger, "Failed to reset crtc ({:?}). Error: {}", handle, err);
if let Err(err) = crtc::set(
self.context.head().head(),
handle,
info.fb(),
&connectors,
info.position(),
info.mode(),
) {
error!(
self.logger,
"Failed to reset crtc ({:?}). Error: {}", handle, err
);
}
}
if let Err(err) = self.drop_master() {
error!(self.logger, "Failed to drop drm master state. Error: {}", err);
error!(
self.logger,
"Failed to drop drm master state. Error: {}", err
);
}
}
}
@ -569,8 +588,10 @@ pub trait DrmHandler<B: Borrow<DrmBackend> + 'static> {
/// ## Panics
/// The device is already borrowed from the given `state`. Borrowing it again will panic
/// and is not necessary as it is already provided via the `device` parameter.
fn ready<'a, S: Into<StateProxy<'a>>>(&mut self, state: S, device: &mut DrmDevice<B>, backend: &StateToken<B>,
crtc: crtc::Handle, frame: u32, duration: Duration);
fn ready<'a, S: Into<StateProxy<'a>>>(
&mut self, state: S, device: &mut DrmDevice<B>, backend: &StateToken<B>, crtc: crtc::Handle,
frame: u32, duration: Duration,
);
/// The `DrmDevice` has thrown an error.
///
/// The related backends are most likely *not* usable anymore and
@ -585,8 +606,9 @@ pub trait DrmHandler<B: Borrow<DrmBackend> + 'static> {
/// Bind a `DrmDevice` to an `EventLoop`,
///
/// This will cause it to recieve events and feed them into an `DrmHandler`
pub fn drm_device_bind<B, H>(evlh: &mut EventLoopHandle, device: StateToken<DrmDevice<B>>, handler: H)
-> IoResult<FdEventSource<(StateToken<DrmDevice<B>>, H)>>
pub fn drm_device_bind<B, H>(
evlh: &mut EventLoopHandle, device: StateToken<DrmDevice<B>>, handler: H
) -> IoResult<FdEventSource<(StateToken<DrmDevice<B>>, H)>>
where
B: From<DrmBackend> + Borrow<DrmBackend> + 'static,
H: DrmHandler<B> + 'static,
@ -624,13 +646,22 @@ where
state.get(&backend_token).borrow().unlock_buffer();
trace!(logger, "Handling event for backend {:?}", event.crtc);
// and then call the user to render the next frame
handler.ready(state, &mut dev, &backend_token, event.crtc, event.frame, event.duration);
handler.ready(
state,
&mut dev,
&backend_token,
event.crtc,
event.frame,
event.duration,
);
}
}
});
}
},
Err(err) => evlh.state().with_value(dev_token, |state, mut dev| handler.error(state, &mut dev, err)),
Err(err) => evlh.state().with_value(dev_token, |state, mut dev| {
handler.error(state, &mut dev, err)
}),
};
},
error: |evlh, &mut (ref mut dev_token, ref mut handler), _, error| {
@ -648,7 +679,10 @@ impl<B: Borrow<DrmBackend> + 'static> SessionObserver for StateToken<DrmDevice<B
let device: &mut DrmDevice<B> = state.get_mut(self);
device.active = false;
if let Err(err) = device.drop_master() {
error!(device.logger, "Failed to drop drm master state. Error: {}", err);
error!(
device.logger,
"Failed to drop drm master state. Error: {}", err
);
}
}
@ -656,13 +690,22 @@ impl<B: Borrow<DrmBackend> + 'static> SessionObserver for StateToken<DrmDevice<B
state.with_value(self, |state, device| {
device.active = true;
if let Err(err) = device.set_master() {
crit!(device.logger, "Failed to acquire drm master again. Error: {}", err);
crit!(
device.logger,
"Failed to acquire drm master again. Error: {}",
err
);
}
for token in device.backends.values() {
let backend = state.get(token);
if let Err(err) = backend.borrow().swap_buffers() {
// TODO handle this better?
error!(device.logger, "Failed to activate crtc ({:?}) again. Error: {}", backend.borrow().crtc(), err);
error!(
device.logger,
"Failed to activate crtc ({:?}) again. Error: {}",
backend.borrow().crtc(),
err
);
}
}
})

View File

@ -238,9 +238,9 @@ pub struct EGLContext<'a, T: NativeSurface> {
impl<'a> EGLContext<'a, ()> {
/// Create a new context from a given `winit`-`Window`
#[cfg(feature = "backend_winit")]
pub fn new_from_winit<L>(window: &'a WinitWindow, attributes: GlAttributes,
reqs: PixelFormatRequirements, logger: L)
-> Result<EGLContext<'a, WinitWindow>>
pub fn new_from_winit<L>(
window: &'a WinitWindow, attributes: GlAttributes, reqs: PixelFormatRequirements, logger: L
) -> Result<EGLContext<'a, WinitWindow>>
where
L: Into<Option<::slog::Logger>>,
{
@ -268,9 +268,9 @@ impl<'a> EGLContext<'a, ()> {
/// Create a new context from a given `gbm::Device`
#[cfg(feature = "backend_drm")]
pub fn new_from_gbm<L, U: 'static>(gbm: &'a GbmDevice<'a>, attributes: GlAttributes,
reqs: PixelFormatRequirements, logger: L)
-> Result<EGLContext<'a, GbmSurface<'a, U>>>
pub fn new_from_gbm<L, U: 'static>(
gbm: &'a GbmDevice<'a>, attributes: GlAttributes, reqs: PixelFormatRequirements, logger: L
) -> Result<EGLContext<'a, GbmSurface<'a, U>>>
where
L: Into<Option<::slog::Logger>>,
{
@ -288,9 +288,10 @@ impl<'a> EGLContext<'a, ()> {
}
impl<'a, T: NativeSurface> EGLContext<'a, T> {
unsafe fn new(native: NativeDisplayPtr, mut attributes: GlAttributes, reqs: PixelFormatRequirements,
log: ::slog::Logger)
-> Result<EGLContext<'a, T>>
unsafe fn new(
native: NativeDisplayPtr, mut attributes: GlAttributes, reqs: PixelFormatRequirements,
log: ::slog::Logger,
) -> Result<EGLContext<'a, T>>
where
T: NativeSurface,
{
@ -322,8 +323,7 @@ impl<'a, T: NativeSurface> EGLContext<'a, T> {
Some(version) => {
error!(
log,
"OpenGLES {:?} is unknown and not supported by the EGL renderer backend",
version
"OpenGLES {:?} is unknown and not supported by the EGL renderer backend", version
);
bail!(ErrorKind::OpenGlVersionNotSupported(version));
}
@ -423,9 +423,9 @@ impl<'a, T: NativeSurface> EGLContext<'a, T> {
)
}
NativeDisplayPtr::X11(display) |
NativeDisplayPtr::Gbm(display) |
NativeDisplayPtr::Wayland(display) => {
NativeDisplayPtr::X11(display)
| NativeDisplayPtr::Gbm(display)
| NativeDisplayPtr::Wayland(display) => {
trace!(log, "Default EGL Display Initialization via GetDisplay");
egl.GetDisplay(display as *mut _)
}
@ -727,9 +727,9 @@ impl<'a, T: NativeSurface> EGLContext<'a, T> {
self.display,
self.config_id,
match surface {
NativeSurfacePtr::X11(ptr) |
NativeSurfacePtr::Wayland(ptr) |
NativeSurfacePtr::Gbm(ptr) => ptr,
NativeSurfacePtr::X11(ptr)
| NativeSurfacePtr::Wayland(ptr)
| NativeSurfacePtr::Gbm(ptr) => ptr,
},
self.surface_attributes.as_ptr(),
)
@ -850,8 +850,10 @@ impl<'context, 'surface, T: NativeSurface> EGLSurface<'context, 'surface, T> {
/// Returns true if the OpenGL surface is the current one in the thread.
pub fn is_current(&self) -> bool {
unsafe { self.context.egl.GetCurrentSurface(ffi::egl::DRAW as _) == self.surface as *const _ &&
self.context.egl.GetCurrentSurface(ffi::egl::READ as _) == self.surface as *const _ }
unsafe {
self.context.egl.GetCurrentSurface(ffi::egl::DRAW as _) == self.surface as *const _
&& self.context.egl.GetCurrentSurface(ffi::egl::READ as _) == self.surface as *const _
}
}
}
@ -905,10 +907,8 @@ impl error::Error for SwapBuffersError {
SwapBuffersError::ContextLost => "The context has been lost, it needs to be recreated",
SwapBuffersError::AlreadySwapped => {
"Buffers are already swapped, swap_buffers was called too many times"
},
SwapBuffersError::Unknown(_) => {
"Unknown Open GL error occurred"
}
SwapBuffersError::Unknown(_) => "Unknown Open GL error occurred",
}
}

View File

@ -29,8 +29,9 @@ pub trait GraphicsBackend {
/// The format is entirely dictated by the concrete implementation and might range
/// from raw image buffers over a fixed list of possible cursor types to simply the
/// void type () to represent no possible customization of the cursor itself.
fn set_cursor_representation(&self, cursor: &Self::CursorFormat, hotspot: (u32, u32))
-> Result<(), Self::Error>;
fn set_cursor_representation(
&self, cursor: &Self::CursorFormat, hotspot: (u32, u32)
) -> Result<(), Self::Error>;
}
pub mod software;

View File

@ -1,6 +1,5 @@
//! Common traits and types used for software rendering on graphics backends
use super::GraphicsBackend;
use std::error::Error;
use wayland_server::protocol::wl_shm::Format;

View File

@ -1,16 +1,16 @@
//! Implementation of input backend trait for types provided by `libinput`
use backend::input as backend;
#[cfg(feature = "backend_session")]
use backend::session::{AsErrno, Session, SessionObserver};
use backend::input as backend;
use input as libinput;
use input::event;
use std::collections::hash_map::{DefaultHasher, Entry, HashMap};
use std::hash::{Hash, Hasher};
use std::io::{Error as IoError, Result as IoResult};
use std::rc::Rc;
use std::path::Path;
use std::os::unix::io::RawFd;
use std::path::Path;
use std::rc::Rc;
use wayland_server::{EventLoopHandle, StateProxy};
use wayland_server::sources::{FdEventSource, FdEventSourceImpl, FdInterest};
@ -583,7 +583,9 @@ impl<S: Session> From<S> for LibinputSessionInterface<S> {
impl<S: Session> libinput::LibinputInterface for LibinputSessionInterface<S> {
fn open_restricted(&mut self, path: &Path, flags: i32) -> Result<RawFd, i32> {
use nix::fcntl::OFlag;
self.0.open(path, OFlag::from_bits_truncate(flags)).map_err(|err| err.as_errno().unwrap_or(1 /*Use EPERM by default*/))
self.0
.open(path, OFlag::from_bits_truncate(flags))
.map_err(|err| err.as_errno().unwrap_or(1 /*Use EPERM by default*/))
}
fn close_restricted(&mut self, fd: RawFd) {
@ -595,9 +597,9 @@ impl<S: Session> libinput::LibinputInterface for LibinputSessionInterface<S> {
///
/// Automatically feeds the backend with incoming events without any manual calls to
/// `dispatch_new_events`. Should be used to achieve the smallest possible latency.
pub fn libinput_bind(backend: LibinputInputBackend, evlh: &mut EventLoopHandle)
-> IoResult<FdEventSource<LibinputInputBackend>>
{
pub fn libinput_bind(
backend: LibinputInputBackend, evlh: &mut EventLoopHandle
) -> IoResult<FdEventSource<LibinputInputBackend>> {
let fd = unsafe { backend.context.fd() };
evlh.add_fd_event_source(
fd,
@ -610,13 +612,13 @@ pub fn libinput_bind(backend: LibinputInputBackend, evlh: &mut EventLoopHandle)
fn fd_event_source_implementation() -> FdEventSourceImpl<LibinputInputBackend> {
FdEventSourceImpl {
ready: |_evlh, ref mut backend, _, _| {
use ::backend::input::InputBackend;
use backend::input::InputBackend;
if let Err(error) = backend.dispatch_new_events() {
warn!(backend.logger, "Libinput errored: {}", error);
}
},
error: |_evlh, ref backend, _, error| {
warn!(backend.logger, "Libinput fd errored: {}", error);
}
},
}
}

View File

@ -46,24 +46,22 @@
//! automatically by the `UdevBackend`, if not done manually).
//! ```
use std::io::Result as IoResult;
use std::path::Path;
use std::os::unix::io::RawFd;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use super::{AsErrno, Session, SessionNotifier, SessionObserver};
use nix::{Error as NixError, Result as NixResult};
use nix::fcntl::{self, open, OFlag};
use nix::libc::c_int;
use nix::sys::signal::{self, Signal};
use nix::sys::stat::{dev_t, major, minor, Mode, fstat};
use nix::unistd::{dup, close};
use wayland_server::EventLoopHandle;
use wayland_server::sources::SignalEventSource;
use nix::sys::stat::{dev_t, fstat, major, minor, Mode};
use nix::unistd::{close, dup};
use std::io::Result as IoResult;
use std::os::unix::io::RawFd;
use std::path::Path;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
#[cfg(feature = "backend_session_udev")]
use udev::Context;
use super::{AsErrno, Session, SessionNotifier, SessionObserver};
use wayland_server::EventLoopHandle;
use wayland_server::sources::SignalEventSource;
#[allow(dead_code)]
mod tty {
@ -102,7 +100,7 @@ mod tty {
pub const VT_PROCESS: i8 = 0x01;
pub const VT_ACKACQ: i32 = 0x02;
extern {
extern "C" {
pub fn __libc_current_sigrtmin() -> i8;
pub fn __libc_current_sigrtmax() -> i8;
}
@ -139,8 +137,8 @@ fn is_tty_device(dev: dev_t, path: Option<&Path>) -> bool {
major(dev) == TTY_MAJOR
};
res || minor(dev) != 0
},
None => major(dev) == TTY_MAJOR || minor(dev) != 0
}
None => major(dev) == TTY_MAJOR || minor(dev) != 0,
}
}
@ -167,34 +165,36 @@ impl DirectSession {
///
/// If you do not provide a tty device path, it will try to open the currently active tty if any.
pub fn new<L>(tty: Option<&Path>, logger: L) -> Result<(DirectSession, DirectSessionNotifier)>
where
L: Into<Option<::slog::Logger>>
where
L: Into<Option<::slog::Logger>>,
{
let logger = ::slog_or_stdlog(logger).new(o!("smithay_module" => "backend_session", "session_type" => "direct/vt"));
let logger = ::slog_or_stdlog(logger)
.new(o!("smithay_module" => "backend_session", "session_type" => "direct/vt"));
let fd = tty
.map(|path| open(path, fcntl::O_RDWR | fcntl::O_CLOEXEC, Mode::empty())
.chain_err(|| ErrorKind::FailedToOpenTTY(String::from(path.to_string_lossy()))))
.unwrap_or(dup(0 /*stdin*/).chain_err(|| ErrorKind::FailedToOpenTTY(String::from("<stdin>"))))?;
let fd = tty.map(|path| {
open(path, fcntl::O_RDWR | fcntl::O_CLOEXEC, Mode::empty())
.chain_err(|| ErrorKind::FailedToOpenTTY(String::from(path.to_string_lossy())))
}).unwrap_or(dup(0 /*stdin*/).chain_err(|| ErrorKind::FailedToOpenTTY(String::from("<stdin>"))))?;
let active = Arc::new(AtomicBool::new(true));
match DirectSession::setup_tty(tty, fd, logger.clone()) {
Ok((vt, old_keyboard_mode, signal)) => {
Ok((DirectSession {
Ok((vt, old_keyboard_mode, signal)) => Ok((
DirectSession {
tty: fd,
active: active.clone(),
vt,
old_keyboard_mode,
logger: logger.new(o!("vt" => format!("{}", vt), "component" => "session")),
}, DirectSessionNotifier {
},
DirectSessionNotifier {
tty: fd,
active,
signals: Vec::new(),
signal,
logger: logger.new(o!("vt" => format!("{}", vt), "component" => "session_notifier"))
}))
},
logger: logger.new(o!("vt" => format!("{}", vt), "component" => "session_notifier")),
},
)),
Err(err) => {
let _ = close(fd);
Err(err)
@ -226,9 +226,11 @@ impl DirectSession {
let mut old_keyboard_mode = 0;
unsafe {
tty::kd_get_kb_mode(tty, &mut old_keyboard_mode).chain_err(|| ErrorKind::FailedToSaveTTYState(vt_num))?;
tty::kd_get_kb_mode(tty, &mut old_keyboard_mode)
.chain_err(|| ErrorKind::FailedToSaveTTYState(vt_num))?;
tty::kd_set_kb_mode(tty, tty::K_OFF).chain_err(|| ErrorKind::FailedToSetTTYKbMode(vt_num))?;
tty::kd_set_mode(tty, tty::KD_GRAPHICS as i32).chain_err(|| ErrorKind::FailedToSetTTYMode(vt_num))?;
tty::kd_set_mode(tty, tty::KD_GRAPHICS as i32)
.chain_err(|| ErrorKind::FailedToSetTTYMode(vt_num))?;
}
// TODO: Support realtime signals
@ -305,19 +307,33 @@ impl Drop for DirectSession {
info!(self.logger, "Deallocating tty {}", self.tty);
if let Err(err) = unsafe { tty::kd_set_kb_mode(self.tty, self.old_keyboard_mode) } {
warn!(self.logger, "Unable to restore vt keyboard mode. Error: {}", err);
warn!(
self.logger,
"Unable to restore vt keyboard mode. Error: {}", err
);
}
if let Err(err) = unsafe { tty::kd_set_mode(self.tty, tty::KD_TEXT as i32) } {
warn!(self.logger, "Unable to restore vt text mode. Error: {}", err);
warn!(
self.logger,
"Unable to restore vt text mode. Error: {}", err
);
}
if let Err(err) = unsafe { tty::vt_set_mode(self.tty, &tty::VtMode {
mode: tty::VT_AUTO,
..Default::default()
}) } {
if let Err(err) = unsafe {
tty::vt_set_mode(
self.tty,
&tty::VtMode {
mode: tty::VT_AUTO,
..Default::default()
},
)
} {
error!(self.logger, "Failed to reset vt handling. Error: {}", err);
}
if let Err(err) = close(self.tty) {
error!(self.logger, "Failed to close tty file descriptor. Error: {}", err);
error!(
self.logger,
"Failed to close tty file descriptor. Error: {}", err
);
}
}
}
@ -350,36 +366,45 @@ impl SessionNotifier for DirectSessionNotifier {
/// Allows the `DirectSessionNotifier` to listen for the incoming signals signalling the session state.
/// If you don't use this function `DirectSessionNotifier` will not correctly tell you the current
/// session state.
pub fn direct_session_bind<L>(notifier: DirectSessionNotifier, evlh: &mut EventLoopHandle, _logger: L)
-> IoResult<SignalEventSource<DirectSessionNotifier>>
pub fn direct_session_bind<L>(
notifier: DirectSessionNotifier, evlh: &mut EventLoopHandle, _logger: L
) -> IoResult<SignalEventSource<DirectSessionNotifier>>
where
L: Into<Option<::slog::Logger>>,
{
let signal = notifier.signal;
evlh.add_signal_event_source(|evlh, notifier, _| {
if notifier.is_active() {
info!(notifier.logger, "Session shall become inactive");
for signal in &mut notifier.signals {
if let &mut Some(ref mut signal) = signal {signal.pause(&mut evlh.state().as_proxy()); }
evlh.add_signal_event_source(
|evlh, notifier, _| {
if notifier.is_active() {
info!(notifier.logger, "Session shall become inactive");
for signal in &mut notifier.signals {
if let &mut Some(ref mut signal) = signal {
signal.pause(&mut evlh.state().as_proxy());
}
}
notifier.active.store(false, Ordering::SeqCst);
unsafe {
tty::vt_rel_disp(notifier.tty, 1).expect("Unable to release tty lock");
}
debug!(notifier.logger, "Session is now inactive");
} else {
debug!(notifier.logger, "Session will become active again");
unsafe {
tty::vt_rel_disp(notifier.tty, tty::VT_ACKACQ).expect("Unable to acquire tty lock");
}
for signal in &mut notifier.signals {
if let &mut Some(ref mut signal) = signal {
signal.activate(&mut evlh.state().as_proxy());
}
}
notifier.active.store(true, Ordering::SeqCst);
info!(notifier.logger, "Session is now active again");
}
notifier.active.store(false, Ordering::SeqCst);
unsafe {
tty::vt_rel_disp(notifier.tty, 1).expect("Unable to release tty lock");
}
debug!(notifier.logger, "Session is now inactive");
} else {
debug!(notifier.logger, "Session will become active again");
unsafe {
tty::vt_rel_disp(notifier.tty, tty::VT_ACKACQ).expect("Unable to acquire tty lock");
}
for signal in &mut notifier.signals {
if let &mut Some(ref mut signal) = signal { signal.activate(&mut evlh.state().as_proxy()); }
}
notifier.active.store(true, Ordering::SeqCst);
info!(notifier.logger, "Session is now active again");
}
}, notifier, signal)
},
notifier,
signal,
)
}
error_chain! {

View File

@ -10,12 +10,12 @@
//! The following mechanisms are currently provided:
//! - direct - legacy tty / virtual terminal kernel api
//!
use std::path::Path;
use std::sync::{Arc, Mutex};
use std::rc::Rc;
use nix::fcntl::OFlag;
use std::cell::RefCell;
use std::os::unix::io::RawFd;
use nix::fcntl::OFlag;
use std::path::Path;
use std::rc::Rc;
use std::sync::{Arc, Mutex};
use wayland_server::StateProxy;
/// General session interface.
@ -83,13 +83,23 @@ pub trait SessionObserver {
impl Session for () {
type Error = ();
fn open(&mut self, _path: &Path, _flags: OFlag) -> Result<RawFd, Self::Error> { Err(()) }
fn close(&mut self, _fd: RawFd) -> Result<(), Self::Error> { Err(()) }
fn open(&mut self, _path: &Path, _flags: OFlag) -> Result<RawFd, Self::Error> {
Err(())
}
fn close(&mut self, _fd: RawFd) -> Result<(), Self::Error> {
Err(())
}
fn change_vt(&mut self, _vt: i32) -> Result<(), Self::Error> { Err(()) }
fn change_vt(&mut self, _vt: i32) -> Result<(), Self::Error> {
Err(())
}
fn is_active(&self) -> bool { false }
fn seat(&self) -> String { String::from("seat0") }
fn is_active(&self) -> bool {
false
}
fn seat(&self) -> String {
String::from("seat0")
}
}
impl<S: Session> Session for Rc<RefCell<S>> {

View File

@ -9,36 +9,51 @@
//! See also `examples/udev.rs` for pure hardware backed example of a compositor utilizing this
//! backend.
use udev::{Context, MonitorBuilder, MonitorSocket, Event, EventType, Enumerator, Result as UdevResult};
use backend::drm::{drm_device_bind, DrmBackend, DrmDevice, DrmHandler};
use backend::session::{Session, SessionObserver};
use nix::fcntl;
use nix::sys::stat::{dev_t, fstat};
use std::borrow::Borrow;
use std::collections::HashMap;
use std::io::{Error as IoError, Result as IoResult};
use std::ffi::OsString;
use std::io::{Error as IoError, Result as IoResult};
use std::mem::drop;
use std::path::{PathBuf, Path};
use std::os::unix::io::AsRawFd;
use wayland_server::{EventLoopHandle, StateToken, StateProxy};
use std::path::{Path, PathBuf};
use udev::{Context, Enumerator, Event, EventType, MonitorBuilder, MonitorSocket, Result as UdevResult};
use wayland_server::{EventLoopHandle, StateProxy, StateToken};
use wayland_server::sources::{FdEventSource, FdEventSourceImpl, FdInterest};
use ::backend::drm::{DrmDevice, DrmBackend, DrmHandler, drm_device_bind};
use ::backend::session::{Session, SessionObserver};
/// Graphical backend that monitors available drm devices.
///
/// Provides a way to automatically initialize a `DrmDevice` for available gpus and notifies the
/// given handler of any changes. Can be used to provide hot-plug functionality for gpus and
/// attached monitors.
pub struct UdevBackend<B: Borrow<DrmBackend> + 'static, H: DrmHandler<B> + 'static, S: Session + 'static, T: UdevHandler<B, H> + 'static> {
devices: HashMap<dev_t, (StateToken<DrmDevice<B>>, FdEventSource<(StateToken<DrmDevice<B>>, H)>)>,
pub struct UdevBackend<
B: Borrow<DrmBackend> + 'static,
H: DrmHandler<B> + 'static,
S: Session + 'static,
T: UdevHandler<B, H> + 'static,
> {
devices: HashMap<
dev_t,
(
StateToken<DrmDevice<B>>,
FdEventSource<(StateToken<DrmDevice<B>>, H)>,
),
>,
monitor: MonitorSocket,
session: S,
handler: T,
logger: ::slog::Logger,
}
impl<B: From<DrmBackend> + Borrow<DrmBackend> + 'static, H: DrmHandler<B> + 'static, S: Session + 'static, T: UdevHandler<B, H> + 'static> UdevBackend<B, H, S, T> {
impl<
B: From<DrmBackend> + Borrow<DrmBackend> + 'static,
H: DrmHandler<B> + 'static,
S: Session + 'static,
T: UdevHandler<B, H> + 'static,
> UdevBackend<B, H, S, T> {
/// Creates a new `UdevBackend` and adds it to the given `EventLoop`'s state.
///
/// ## Arguments
@ -47,14 +62,11 @@ impl<B: From<DrmBackend> + Borrow<DrmBackend> + 'static, H: DrmHandler<B> + 'sta
/// `session` - A session used to open and close devices as they become available
/// `handler` - User-provided handler to respond to any detected changes
/// `logger` - slog Logger to be used by the backend and its `DrmDevices`.
pub fn new<'a, L>(mut evlh: &mut EventLoopHandle,
context: &Context,
mut session: S,
mut handler: T,
logger: L)
-> Result<StateToken<UdevBackend<B, H, S, T>>>
pub fn new<'a, L>(
mut evlh: &mut EventLoopHandle, context: &Context, mut session: S, mut handler: T, logger: L
) -> Result<StateToken<UdevBackend<B, H, S, T>>>
where
L: Into<Option<::slog::Logger>>
L: Into<Option<::slog::Logger>>,
{
let logger = ::slog_or_stdlog(logger).new(o!("smithay_module" => "backend_udev"));
let seat = session.seat();
@ -125,8 +137,12 @@ impl<B: From<DrmBackend> + Borrow<DrmBackend> + 'static, H: DrmHandler<B> + 'sta
.collect::<HashMap<dev_t, (StateToken<DrmDevice<B>>, FdEventSource<(StateToken<DrmDevice<B>>, H)>)>>();
let mut builder = MonitorBuilder::new(context).chain_err(|| ErrorKind::FailedToInitMonitor)?;
builder.match_subsystem("drm").chain_err(|| ErrorKind::FailedToInitMonitor)?;
let monitor = builder.listen().chain_err(|| ErrorKind::FailedToInitMonitor)?;
builder
.match_subsystem("drm")
.chain_err(|| ErrorKind::FailedToInitMonitor)?;
let monitor = builder
.listen()
.chain_err(|| ErrorKind::FailedToInitMonitor)?;
Ok(evlh.state().insert(UdevBackend {
devices,
@ -154,14 +170,22 @@ impl<B: From<DrmBackend> + Borrow<DrmBackend> + 'static, H: DrmHandler<B> + 'sta
let fd = device.as_raw_fd();
drop(device);
if let Err(err) = self.session.close(fd) {
warn!(self.logger, "Failed to close device. Error: {:?}. Ignoring", err);
warn!(
self.logger,
"Failed to close device. Error: {:?}. Ignoring", err
);
};
}
info!(self.logger, "All devices closed");
}
}
impl<B: Borrow<DrmBackend> + 'static, H: DrmHandler<B> + 'static, S: Session + 'static, T: UdevHandler<B, H> + 'static> SessionObserver for StateToken<UdevBackend<B, H, S, T>> {
impl<
B: Borrow<DrmBackend> + 'static,
H: DrmHandler<B> + 'static,
S: Session + 'static,
T: UdevHandler<B, H> + 'static,
> SessionObserver for StateToken<UdevBackend<B, H, S, T>> {
fn pause<'a>(&mut self, state: &mut StateProxy<'a>) {
state.with_value(self, |state, udev| {
for &mut (ref mut device, _) in udev.devices.values_mut() {
@ -183,8 +207,9 @@ impl<B: Borrow<DrmBackend> + 'static, H: DrmHandler<B> + 'static, S: Session + '
///
/// Allows the backend to recieve kernel events and thus to drive the `UdevHandler`.
/// No runtime functionality can be provided without using this function.
pub fn udev_backend_bind<B, S, H, T>(evlh: &mut EventLoopHandle, udev: StateToken<UdevBackend<B, H, S, T>>)
-> IoResult<FdEventSource<StateToken<UdevBackend<B, H, S, T>>>>
pub fn udev_backend_bind<B, S, H, T>(
evlh: &mut EventLoopHandle, udev: StateToken<UdevBackend<B, H, S, T>>
) -> IoResult<FdEventSource<StateToken<UdevBackend<B, H, S, T>>>>
where
B: From<DrmBackend> + Borrow<DrmBackend> + 'static,
H: DrmHandler<B> + 'static,
@ -192,16 +217,10 @@ where
S: Session + 'static,
{
let fd = evlh.state().get(&udev).monitor.as_raw_fd();
evlh.add_fd_event_source(
fd,
fd_event_source_implementation(),
udev,
FdInterest::READ,
)
evlh.add_fd_event_source(fd, fd_event_source_implementation(), udev, FdInterest::READ)
}
fn fd_event_source_implementation<B, S, H, T>()
-> FdEventSourceImpl<StateToken<UdevBackend<B, H, S, T>>>
fn fd_event_source_implementation<B, S, H, T>() -> FdEventSourceImpl<StateToken<UdevBackend<B, H, S, T>>>
where
B: From<DrmBackend> + Borrow<DrmBackend> + 'static,
H: DrmHandler<B> + 'static,
@ -210,7 +229,11 @@ where
{
FdEventSourceImpl {
ready: |mut evlh, token, _, _| {
let events = evlh.state().get(token).monitor.clone().collect::<Vec<Event>>();
let events = evlh.state()
.get(token)
.monitor
.clone()
.collect::<Vec<Event>>();
for event in events {
match event.event_type() {
// New device
@ -218,30 +241,49 @@ where
info!(evlh.state().get(token).logger, "Device Added");
if let (Some(path), Some(devnum)) = (event.devnode(), event.devnum()) {
let mut device = {
match unsafe { DrmDevice::new_from_fd(
{
let logger = evlh.state().get(token).logger.clone();
match evlh.state().get_mut(token).session.open(path, fcntl::O_RDWR | fcntl::O_CLOEXEC | fcntl::O_NOCTTY | fcntl::O_NONBLOCK) {
Ok(fd) => fd,
Err(err) => {
warn!(logger, "Unable to open drm device {:?}, Error: {:?}. Skipping", path, err);
continue;
match unsafe {
DrmDevice::new_from_fd(
{
let logger = evlh.state().get(token).logger.clone();
match evlh.state().get_mut(token).session.open(
path,
fcntl::O_RDWR | fcntl::O_CLOEXEC | fcntl::O_NOCTTY
| fcntl::O_NONBLOCK,
) {
Ok(fd) => fd,
Err(err) => {
warn!(logger, "Unable to open drm device {:?}, Error: {:?}. Skipping", path, err);
continue;
}
}
}
}, evlh.state().get(token).logger.clone()
) } {
},
evlh.state().get(token).logger.clone(),
)
} {
Ok(dev) => dev,
Err(err) => {
warn!(evlh.state().get(token).logger, "Failed to initialize device {:?}. Error: {}. Skipping", path, err);
warn!(
evlh.state().get(token).logger,
"Failed to initialize device {:?}. Error: {}. Skipping",
path,
err
);
continue;
}
}
};
match evlh.state().with_value(token, |state, udev| udev.handler.device_added(state, &mut device)) {
match evlh.state().with_value(token, |state, udev| {
udev.handler.device_added(state, &mut device)
}) {
Some(drm_handler) => {
let dev_token = evlh.state().insert(device);
if let Ok(fd_event_source) = drm_device_bind(&mut evlh, dev_token.clone(), drm_handler) {
evlh.state().get_mut(token).devices.insert(devnum, (dev_token, fd_event_source));
if let Ok(fd_event_source) =
drm_device_bind(&mut evlh, dev_token.clone(), drm_handler)
{
evlh.state()
.get_mut(token)
.devices
.insert(devnum, (dev_token, fd_event_source));
} else {
evlh.state().with_value(token, |state, udev| {
let mut state: StateProxy = state.into();
@ -250,42 +292,52 @@ where
let fd = device.as_raw_fd();
drop(device);
if let Err(err) = udev.session.close(fd) {
warn!(udev.logger, "Failed to close dropped device. Error: {:?}. Ignoring", err);
warn!(
udev.logger,
"Failed to close dropped device. Error: {:?}. Ignoring",
err
);
};
})
}
},
}
None => {
let fd = device.as_raw_fd();
drop(device);
evlh.state().with_value(token, |_state, udev| {
if let Err(err) = udev.session.close(fd) {
warn!(udev.logger, "Failed to close unused device. Error: {:?}", err);
warn!(
udev.logger,
"Failed to close unused device. Error: {:?}", err
);
}
})
},
}
};
}
},
}
// Device removed
EventType::Remove => {
evlh.state().with_value(token, |state, udev| {
info!(udev.logger, "Device Remove");
if let Some(devnum) = event.devnum() {
if let Some((device, fd_event_source)) = udev.devices.remove(&devnum) {
fd_event_source.remove();
let mut state: StateProxy = state.into();
udev.handler.device_removed(&mut state, &device);
let device = state.remove(device);
let fd = device.as_raw_fd();
drop(device);
if let Err(err) = udev.session.close(fd) {
warn!(udev.logger, "Failed to close device {:?}. Error: {:?}. Ignoring", event.sysname(), err);
};
}
EventType::Remove => evlh.state().with_value(token, |state, udev| {
info!(udev.logger, "Device Remove");
if let Some(devnum) = event.devnum() {
if let Some((device, fd_event_source)) = udev.devices.remove(&devnum) {
fd_event_source.remove();
let mut state: StateProxy = state.into();
udev.handler.device_removed(&mut state, &device);
let device = state.remove(device);
let fd = device.as_raw_fd();
drop(device);
if let Err(err) = udev.session.close(fd) {
warn!(
udev.logger,
"Failed to close device {:?}. Error: {:?}. Ignoring",
event.sysname(),
err
);
};
}
})
},
}
}),
// New connector
EventType::Change => evlh.state().with_value(token, |state, udev| {
info!(udev.logger, "Device Changed");
@ -301,25 +353,28 @@ where
info!(udev.logger, "changed, but no devnum");
}
}),
_ => {},
_ => {}
}
}
},
error: |evlh, token, _, err| {
evlh.state().with_value(token, |state, udev| udev.handler.error(state, err))
evlh.state()
.with_value(token, |state, udev| udev.handler.error(state, err))
},
}
}
/// Handler for the `UdevBackend`, allows to open, close and update drm devices as they change during runtime.
pub trait UdevHandler<B: Borrow<DrmBackend> + 'static, H: DrmHandler<B> + 'static> {
pub trait UdevHandler<B: Borrow<DrmBackend> + 'static, H: DrmHandler<B> + 'static>
{
/// Called on initialization for every known device and when a new device is detected.
///
/// Returning a `DrmHandler` will initialize the device, returning `None` will ignore the device.
///
/// ## Panics
/// Panics if you try to borrow the token of the belonging `UdevBackend` using this `StateProxy`.
fn device_added<'a, S: Into<StateProxy<'a>>>(&mut self, state: S, device: &mut DrmDevice<B>) -> Option<H>;
fn device_added<'a, S: Into<StateProxy<'a>>>(&mut self, state: S, device: &mut DrmDevice<B>)
-> Option<H>;
/// Called when an open device is changed.
///
/// This usually indicates that some connectors did become available or were unplugged. The handler
@ -353,7 +408,11 @@ pub fn primary_gpu<S: AsRef<str>>(context: &Context, seat: S) -> UdevResult<Opti
let mut result = None;
for device in enumerator.scan_devices()? {
if device.property_value("ID_SEAT").map(|x| x.to_os_string()).unwrap_or(OsString::from("seat0")) == *seat.as_ref() {
if device
.property_value("ID_SEAT")
.map(|x| x.to_os_string())
.unwrap_or(OsString::from("seat0")) == *seat.as_ref()
{
if let Some(pci) = device.parent_with_subsystem(Path::new("pci"))? {
if let Some(id) = pci.attribute_value("boot_vga") {
if id == "1" {
@ -375,11 +434,16 @@ pub fn all_gpus<S: AsRef<str>>(context: &Context, seat: S) -> UdevResult<Vec<Pat
let mut enumerator = Enumerator::new(context)?;
enumerator.match_subsystem("drm")?;
enumerator.match_sysname("card[0-9]*")?;
Ok(enumerator.scan_devices()?
.filter(|device| device.property_value("ID_SEAT").map(|x| x.to_os_string()).unwrap_or(OsString::from("seat0")) == *seat.as_ref())
Ok(enumerator
.scan_devices()?
.filter(|device| {
device
.property_value("ID_SEAT")
.map(|x| x.to_os_string())
.unwrap_or(OsString::from("seat0")) == *seat.as_ref()
})
.flat_map(|device| device.devnode().map(PathBuf::from))
.collect()
)
.collect())
}
error_chain! {

View File

@ -99,8 +99,9 @@ where
/// Create a new `WinitGraphicsBackend`, which implements the `EGLGraphicsBackend`
/// graphics backend trait, from a given `WindowBuilder` struct and a corresponding
/// `WinitInputBackend`, which implements the `InputBackend` trait
pub fn init_from_builder<L>(builder: WindowBuilder, logger: L)
-> Result<(WinitGraphicsBackend, WinitInputBackend)>
pub fn init_from_builder<L>(
builder: WindowBuilder, logger: L
) -> Result<(WinitGraphicsBackend, WinitInputBackend)>
where
L: Into<Option<::slog::Logger>>,
{
@ -120,8 +121,9 @@ where
/// graphics backend trait, from a given `WindowBuilder` struct, as well as given
/// `GlAttributes` for further customization of the rendering pipeline and a
/// corresponding `WinitInputBackend`, which implements the `InputBackend` trait.
pub fn init_from_builder_with_gl_attr<L>(builder: WindowBuilder, attributes: GlAttributes, logger: L)
-> Result<(WinitGraphicsBackend, WinitInputBackend)>
pub fn init_from_builder_with_gl_attr<L>(
builder: WindowBuilder, attributes: GlAttributes, logger: L
) -> Result<(WinitGraphicsBackend, WinitInputBackend)>
where
L: Into<Option<::slog::Logger>>,
{
@ -190,8 +192,9 @@ impl GraphicsBackend for WinitGraphicsBackend {
self.window.head().set_cursor_position(x as i32, y as i32)
}
fn set_cursor_representation(&self, cursor: &Self::CursorFormat, _hotspot: (u32, u32))
-> ::std::result::Result<(), ()> {
fn set_cursor_representation(
&self, cursor: &Self::CursorFormat, _hotspot: (u32, u32)
) -> ::std::result::Result<(), ()> {
// Cannot log this one, as `CursorFormat` is not `Debug` and should not be
debug!(self.logger, "Changing cursor representation");
self.window.head().set_cursor(*cursor);
@ -228,7 +231,8 @@ impl EGLGraphicsBackend for WinitGraphicsBackend {
}
fn is_current(&self) -> bool {
self.window.rent(|egl| egl.rent_all(|egl| egl.context.is_current() && egl.surface.is_current()))
self.window
.rent(|egl| egl.rent_all(|egl| egl.context.is_current() && egl.surface.is_current()))
}
unsafe fn make_current(&self) -> ::std::result::Result<(), SwapBuffersError> {
@ -371,10 +375,10 @@ impl PointerAxisEvent for WinitMouseWheelEvent {
fn amount(&self) -> f64 {
match (self.axis, self.delta) {
(Axis::Horizontal, MouseScrollDelta::LineDelta(x, _)) |
(Axis::Horizontal, MouseScrollDelta::PixelDelta(x, _)) => x as f64,
(Axis::Vertical, MouseScrollDelta::LineDelta(_, y)) |
(Axis::Vertical, MouseScrollDelta::PixelDelta(_, y)) => y as f64,
(Axis::Horizontal, MouseScrollDelta::LineDelta(x, _))
| (Axis::Horizontal, MouseScrollDelta::PixelDelta(x, _)) => x as f64,
(Axis::Vertical, MouseScrollDelta::LineDelta(_, y))
| (Axis::Vertical, MouseScrollDelta::PixelDelta(_, y)) => y as f64,
}
}
}
@ -624,8 +628,10 @@ impl InputBackend for WinitInputBackend {
trace!(logger, "Resizing window to {:?}", (x, y));
window.head().set_inner_size(x, y);
window.rent(|egl| {
egl.rent(|surface| if let Some(wegl_surface) = (**surface).as_ref() {
wegl_surface.resize(x as i32, y as i32, 0, 0)
egl.rent(|surface| {
if let Some(wegl_surface) = (**surface).as_ref() {
wegl_surface.resize(x as i32, y as i32, 0, 0)
}
})
});
}

View File

@ -11,9 +11,10 @@ use wayland_server::protocol::{wl_compositor, wl_region, wl_subcompositor, wl_su
* wl_compositor
*/
pub(crate) fn compositor_bind<U, R, ID>(evlh: &mut EventLoopHandle, idata: &mut SurfaceIData<U, R, ID>,
_: &Client, compositor: wl_compositor::WlCompositor)
where
pub(crate) fn compositor_bind<U, R, ID>(
evlh: &mut EventLoopHandle, idata: &mut SurfaceIData<U, R, ID>, _: &Client,
compositor: wl_compositor::WlCompositor,
) where
U: Default + 'static,
R: Default + 'static,
ID: 'static,
@ -65,8 +66,9 @@ pub struct SurfaceIData<U, R, 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> {
pub(crate) fn make(
log: ::slog::Logger, implem: SurfaceUserImplementation<U, R, ID>, idata: ID
) -> SurfaceIData<U, R, ID> {
SurfaceIData {
log: log,
implem: implem,
@ -86,9 +88,7 @@ impl<U, R, ID> Clone for SurfaceIData<U, R, ID> {
}
pub(crate) fn surface_implementation<U: 'static, R: 'static, ID: 'static>(
)
-> wl_surface::Implementation<SurfaceIData<U, R, ID>>
{
) -> wl_surface::Implementation<SurfaceIData<U, R, ID>> {
wl_surface::Implementation {
attach: |_, _, _, surface, buffer, x, y| unsafe {
SurfaceData::<U, R>::with_data(surface, |d| {
@ -199,9 +199,9 @@ fn destroy_region(region: &wl_region::WlRegion) {
* wl_subcompositor
*/
pub(crate) fn subcompositor_bind<U, R>(evlh: &mut EventLoopHandle, _: &mut (), _: &Client,
subcompositor: wl_subcompositor::WlSubcompositor)
where
pub(crate) fn subcompositor_bind<U, R>(
evlh: &mut EventLoopHandle, _: &mut (), _: &Client, subcompositor: wl_subcompositor::WlSubcompositor
) where
R: RoleType + Role<SubsurfaceRole> + 'static,
U: 'static,
{

View File

@ -314,11 +314,11 @@ where
///
/// If the surface not managed by the CompositorGlobal that provided this token, this
/// will panic (having more than one compositor is not supported).
pub fn with_surface_tree_upward<F, T>(&self, surface: &wl_surface::WlSurface, initial: T, f: F)
-> Result<(), ()>
pub fn with_surface_tree_upward<F, T>(
&self, surface: &wl_surface::WlSurface, initial: T, f: F
) -> Result<(), ()>
where
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T)
-> TraversalAction<T>,
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> TraversalAction<T>,
{
assert!(
resource_is_registered(
@ -340,11 +340,11 @@ where
/// supposed to be drawn: top-most first.
///
/// Behavior is the same as `with_surface_tree_upward`.
pub fn with_surface_tree_downward<F, T>(&self, surface: &wl_surface::WlSurface, initial: T, f: F)
-> Result<(), ()>
pub fn with_surface_tree_downward<F, T>(
&self, surface: &wl_surface::WlSurface, initial: T, f: F
) -> Result<(), ()>
where
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T)
-> TraversalAction<T>,
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> TraversalAction<T>,
{
assert!(
resource_is_registered(
@ -426,7 +426,6 @@ impl<U: 'static, R: RoleType + 'static, ID: 'static> CompositorToken<U, R, ID> {
unsafe { SurfaceData::<U, R>::has_role::<RoleData>(surface) }
}
/// Register that this surface has given role with default data
///
/// Fails if the surface already has a role.
@ -454,8 +453,9 @@ impl<U: 'static, R: RoleType + 'static, ID: 'static> CompositorToken<U, R, ID> {
///
/// 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_with<RoleData>(&self, surface: &wl_surface::WlSurface, data: RoleData)
-> Result<(), RoleData>
pub fn give_role_with<RoleData>(
&self, surface: &wl_surface::WlSurface, data: RoleData
) -> Result<(), RoleData>
where
R: Role<RoleData>,
{
@ -475,8 +475,9 @@ impl<U: 'static, R: RoleType + 'static, ID: 'static> CompositorToken<U, R, ID> {
///
/// 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 with_role_data<RoleData, F, T>(&self, surface: &wl_surface::WlSurface, f: F)
-> Result<T, WrongRole>
pub fn with_role_data<RoleData, F, T>(
&self, surface: &wl_surface::WlSurface, f: F
) -> Result<T, WrongRole>
where
R: Role<RoleData>,
F: FnOnce(&mut RoleData) -> T,
@ -533,12 +534,12 @@ impl<U: 'static, R: RoleType + 'static, ID: 'static> CompositorToken<U, R, ID> {
/// It also returns the two global handles, in case you whish to remove these
/// globals from the event loop in the future.
pub fn compositor_init<U, R, ID, L>(
evl: &mut EventLoop, implem: SurfaceUserImplementation<U, R, ID>, idata: ID, logger: L)
-> (
CompositorToken<U, R, ID>,
Global<wl_compositor::WlCompositor, self::handlers::SurfaceIData<U, R, ID>>,
Global<wl_subcompositor::WlSubcompositor, ()>,
)
evl: &mut EventLoop, implem: SurfaceUserImplementation<U, R, ID>, idata: ID, logger: L
) -> (
CompositorToken<U, R, ID>,
Global<wl_compositor::WlCompositor, self::handlers::SurfaceIData<U, R, ID>>,
Global<wl_subcompositor::WlSubcompositor, ()>,
)
where
L: Into<Option<::slog::Logger>>,
U: Default + 'static,
@ -580,10 +581,10 @@ pub struct SurfaceUserImplementation<U, R, ID> {
/// 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
pub commit: fn(
evlh: &mut EventLoopHandle,
idata: &mut ID,
surface: &wl_surface::WlSurface,
token: CompositorToken<U, R, ID>,
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
///
@ -593,11 +594,11 @@ pub struct SurfaceUserImplementation<U, R, ID> {
/// 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
pub frame: fn(
evlh: &mut EventLoopHandle,
idata: &mut ID,
surface: &wl_surface::WlSurface,
callback: wl_callback::WlCallback,
token: CompositorToken<U, R, ID>,
evlh: &mut EventLoopHandle,
idata: &mut ID,
surface: &wl_surface::WlSurface,
callback: wl_callback::WlCallback,
token: CompositorToken<U, R, ID>,
),
}

View File

@ -132,8 +132,9 @@ impl<U: 'static, R: RoleType + 'static> SurfaceData<U, R> {
/// Register that this surface has a role with given data
///
/// Fails if it already has one and returns the data
pub unsafe fn give_role_with<RoleData>(surface: &wl_surface::WlSurface, data: RoleData)
-> Result<(), RoleData>
pub unsafe fn give_role_with<RoleData>(
surface: &wl_surface::WlSurface, data: RoleData
) -> Result<(), RoleData>
where
R: Role<RoleData>,
{
@ -158,8 +159,9 @@ impl<U: 'static, R: RoleType + 'static> SurfaceData<U, R> {
}
/// Access to the role data
pub unsafe fn with_role_data<RoleData, F, T>(surface: &wl_surface::WlSurface, f: F)
-> Result<T, WrongRole>
pub unsafe fn with_role_data<RoleData, F, T>(
surface: &wl_surface::WlSurface, f: F
) -> Result<T, WrongRole>
where
R: Role<RoleData>,
F: FnOnce(&mut RoleData) -> T,
@ -177,8 +179,9 @@ impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R>
///
/// if this surface already has a role, does nothing and fails, otherwise
/// its role is now to be a subsurface
pub unsafe fn set_parent(child: &wl_surface::WlSurface, parent: &wl_surface::WlSurface)
-> Result<(), ()> {
pub unsafe fn set_parent(
child: &wl_surface::WlSurface, parent: &wl_surface::WlSurface
) -> Result<(), ()> {
debug_assert!(child.status() == Liveness::Alive);
debug_assert!(parent.status() == Liveness::Alive);
@ -246,9 +249,9 @@ impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R>
/// Reorders a surface relative to one of its sibling
///
/// Fails if `relative_to` is not a sibling or parent of `surface`.
pub unsafe fn reorder(surface: &wl_surface::WlSurface, to: Location,
relative_to: &wl_surface::WlSurface)
-> Result<(), ()> {
pub unsafe fn reorder(
surface: &wl_surface::WlSurface, to: Location, relative_to: &wl_surface::WlSurface
) -> Result<(), ()> {
let parent = {
let data_mutex = Self::get_data(surface);
let data_guard = data_mutex.lock().unwrap();
@ -316,17 +319,15 @@ impl<U: 'static, R: 'static> SurfaceData<U, R> {
/// false will cause an early-stopping.
pub unsafe fn map_tree<F, T>(root: &wl_surface::WlSurface, initial: T, mut f: F, reverse: bool)
where
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T)
-> TraversalAction<T>,
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> TraversalAction<T>,
{
// helper function for recursion
unsafe fn map<U: 'static, R: 'static, F, T>(surface: &wl_surface::WlSurface,
root: &wl_surface::WlSurface, initial: &T, f: &mut F,
reverse: bool)
-> bool
unsafe fn map<U: 'static, R: 'static, F, T>(
surface: &wl_surface::WlSurface, root: &wl_surface::WlSurface, initial: &T, f: &mut F,
reverse: bool,
) -> bool
where
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T)
-> TraversalAction<T>,
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> TraversalAction<T>,
{
// stop if we met the root, so to not deadlock/inifinte loop
if surface.equals(root) {

View File

@ -113,11 +113,11 @@ impl Output {
/// returns the state token allowing you to access it, as well as the global handle,
/// in case you whish to remove this global in the future.
pub fn new<L>(
evl: &mut EventLoop, name: String, physical: PhysicalProperties, logger: L)
-> (
StateToken<Output>,
Global<wl_output::WlOutput, StateToken<Output>>,
)
evl: &mut EventLoop, name: String, physical: PhysicalProperties, logger: L
) -> (
StateToken<Output>,
Global<wl_output::WlOutput, StateToken<Output>>,
)
where
L: Into<Option<::slog::Logger>>,
{
@ -229,8 +229,10 @@ impl Output {
/// internal list.
///
/// By default, transform status is `Normal`, and scale is `1`.
pub fn change_current_state(&mut self, new_mode: Option<Mode>,
new_transform: Option<wl_output::Transform>, new_scale: Option<i32>) {
pub fn change_current_state(
&mut self, new_mode: Option<Mode>, new_transform: Option<wl_output::Transform>,
new_scale: Option<i32>,
) {
if let Some(mode) = new_mode {
if self.modes.iter().find(|&m| *m == mode).is_none() {
self.modes.push(mode);
@ -283,8 +285,9 @@ impl Output {
}
}
fn output_bind(evlh: &mut EventLoopHandle, token: &mut StateToken<Output>, _: &Client,
global: wl_output::WlOutput) {
fn output_bind(
evlh: &mut EventLoopHandle, token: &mut StateToken<Output>, _: &Client, global: wl_output::WlOutput
) {
evlh.register(&global, output_implementation(), token.clone(), None);
evlh.state().get_mut(token).new_global(global);
}

View File

@ -66,9 +66,10 @@ struct KbdInternal {
}
impl KbdInternal {
fn new(rules: &str, model: &str, layout: &str, variant: &str, options: Option<String>,
repeat_rate: i32, repeat_delay: i32)
-> Result<KbdInternal, ()> {
fn new(
rules: &str, model: &str, layout: &str, variant: &str, options: Option<String>, repeat_rate: i32,
repeat_delay: i32,
) -> Result<KbdInternal, ()> {
// we create a new contex for each keyboard because libxkbcommon is actually NOT threadsafe
// so confining it inside the KbdInternal allows us to use Rusts mutability rules to make
// sure nothing goes wrong.
@ -168,10 +169,10 @@ pub enum Error {
}
/// Create a keyboard handler from a set of RMLVO rules
pub(crate) fn create_keyboard_handler(rules: &str, model: &str, layout: &str, variant: &str,
options: Option<String>, repeat_delay: i32, repeat_rate: i32,
logger: &::slog::Logger)
-> Result<KeyboardHandle, Error> {
pub(crate) fn create_keyboard_handler(
rules: &str, model: &str, layout: &str, variant: &str, options: Option<String>, repeat_delay: i32,
repeat_rate: i32, logger: &::slog::Logger,
) -> Result<KeyboardHandle, Error> {
let log = logger.new(o!("smithay_module" => "xkbcommon_handler"));
info!(log, "Initializing a xkbcommon handler with keymap query";
"rules" => rules, "model" => model, "layout" => layout, "variant" => variant,
@ -192,7 +193,6 @@ pub(crate) fn create_keyboard_handler(rules: &str, model: &str, layout: &str, va
info!(log, "Loaded Keymap"; "name" => internal.keymap.layouts().next());
// prepare a tempfile with the keymap, to send it to clients
let mut keymap_file = tempfile().map_err(Error::IoError)?;
let keymap_data = internal.keymap.get_as_string(xkb::KEYMAP_FORMAT_TEXT_V1);

View File

@ -87,8 +87,9 @@ impl Seat {
/// You are provided with the state token to retrieve it (allowing
/// you to add or remove capabilities from it), and the global handle,
/// in case you want to remove it.
pub fn new<L>(evl: &mut EventLoop, name: String, logger: L)
-> (StateToken<Seat>, Global<wl_seat::WlSeat, StateToken<Seat>>)
pub fn new<L>(
evl: &mut EventLoop, name: String, logger: L
) -> (StateToken<Seat>, Global<wl_seat::WlSeat, StateToken<Seat>>)
where
L: Into<Option<::slog::Logger>>,
{
@ -158,9 +159,10 @@ impl Seat {
/// Calling this method on a seat that already has a keyboard capability
/// will overwrite it, and will be seen by the clients as if the
/// keyboard was unplugged and a new one was plugged.
pub fn add_keyboard(&mut self, model: &str, layout: &str, variant: &str, options: Option<String>,
repeat_delay: i32, repeat_rate: i32)
-> Result<KeyboardHandle, KeyboardError> {
pub fn add_keyboard(
&mut self, model: &str, layout: &str, variant: &str, options: Option<String>, repeat_delay: i32,
repeat_rate: i32,
) -> Result<KeyboardHandle, KeyboardError> {
let keyboard = self::keyboard::create_keyboard_handler(
"evdev", // we need this one
model,
@ -229,8 +231,9 @@ impl Seat {
}
}
fn seat_global_bind(evlh: &mut EventLoopHandle, token: &mut StateToken<Seat>, _: &Client,
seat: wl_seat::WlSeat) {
fn seat_global_bind(
evlh: &mut EventLoopHandle, token: &mut StateToken<Seat>, _: &Client, seat: wl_seat::WlSeat
) {
evlh.register(&seat, seat_implementation(), token.clone(), None);
let seat_mgr = evlh.state().get_mut(token);
seat.name(seat_mgr.name.clone());

View File

@ -302,12 +302,12 @@ impl<U, R, CID, SID, SD> Clone for ShellSurfaceIData<U, R, CID, SID, SD> {
/// globals from the event loop in the future.
pub fn shell_init<U, R, CID, SID, SD, L>(
evl: &mut EventLoop, token: CompositorToken<U, R, CID>,
implementation: ShellSurfaceUserImplementation<U, R, CID, SID, SD>, idata: SID, logger: L)
-> (
StateToken<ShellState<U, R, CID, SD>>,
Global<wl_shell::WlShell, ShellSurfaceIData<U, R, CID, SID, SD>>,
Global<zxdg_shell_v6::ZxdgShellV6, ShellSurfaceIData<U, R, CID, SID, SD>>,
)
implementation: ShellSurfaceUserImplementation<U, R, CID, SID, SD>, idata: SID, logger: L,
) -> (
StateToken<ShellState<U, R, CID, SD>>,
Global<wl_shell::WlShell, ShellSurfaceIData<U, R, CID, SID, SD>>,
Global<zxdg_shell_v6::ZxdgShellV6, ShellSurfaceIData<U, R, CID, SID, SD>>,
)
where
U: 'static,
R: Role<ShellSurfaceRole> + 'static,
@ -449,7 +449,8 @@ impl<SD> ShellClient<SD> {
}
match self.kind {
ShellClientKind::Wl(ref shell) => {
let mutex = unsafe { &*(shell.get_user_data() as *mut self::wl_handlers::ShellUserData<SD>) };
let mutex =
unsafe { &*(shell.get_user_data() as *mut self::wl_handlers::ShellUserData<SD>) };
let mut guard = mutex.lock().unwrap();
if guard.0.pending_ping == 0 {
return Err(());
@ -486,7 +487,8 @@ impl<SD> ShellClient<SD> {
}
match self.kind {
ShellClientKind::Wl(ref shell) => {
let mutex = unsafe { &*(shell.get_user_data() as *mut self::wl_handlers::ShellUserData<SD>) };
let mutex =
unsafe { &*(shell.get_user_data() as *mut self::wl_handlers::ShellUserData<SD>) };
let mut guard = mutex.lock().unwrap();
Ok(f(&mut guard.0.data))
}
@ -844,46 +846,44 @@ pub struct ShellSurfaceUserImplementation<U, R, CID, SID, SD> {
///
/// You need to return a `ToplevelConfigure` from this function, which will be sent
/// to the client to configure this surface
pub new_toplevel: fn(
evlh: &mut EventLoopHandle,
idata: &mut SID,
surface: ToplevelSurface<U, R, CID, SD>,
) -> ToplevelConfigure,
pub new_toplevel:
fn(evlh: &mut EventLoopHandle, idata: &mut SID, surface: ToplevelSurface<U, R, CID, SD>)
-> ToplevelConfigure,
/// A new popup surface was created
///
/// You need to return a `PopupConfigure` from this function, which will be sent
/// to the client to configure this surface
pub new_popup: fn(evlh: &mut EventLoopHandle, idata: &mut SID, surface: PopupSurface<U, R, CID, SD>)
-> PopupConfigure,
-> PopupConfigure,
/// The client requested the start of an interactive move for this surface
pub move_: fn(
evlh: &mut EventLoopHandle,
idata: &mut SID,
surface: ToplevelSurface<U, R, CID, SD>,
seat: &wl_seat::WlSeat,
serial: u32,
evlh: &mut EventLoopHandle,
idata: &mut SID,
surface: ToplevelSurface<U, R, CID, SD>,
seat: &wl_seat::WlSeat,
serial: u32,
),
/// The client requested the start of an interactive resize for this surface
///
/// The `edges` argument specifies which part of the window's border is being dragged.
pub resize: fn(
evlh: &mut EventLoopHandle,
idata: &mut SID,
surface: ToplevelSurface<U, R, CID, SD>,
seat: &wl_seat::WlSeat,
serial: u32,
edges: zxdg_toplevel_v6::ResizeEdge,
evlh: &mut EventLoopHandle,
idata: &mut SID,
surface: ToplevelSurface<U, R, CID, SD>,
seat: &wl_seat::WlSeat,
serial: u32,
edges: zxdg_toplevel_v6::ResizeEdge,
),
/// This popup requests a grab of the pointer
///
/// This means it requests to be sent a `popup_done` event when the pointer leaves
/// the grab area.
pub grab: fn(
evlh: &mut EventLoopHandle,
idata: &mut SID,
surface: PopupSurface<U, R, CID, SD>,
seat: &wl_seat::WlSeat,
serial: u32,
evlh: &mut EventLoopHandle,
idata: &mut SID,
surface: PopupSurface<U, R, CID, SD>,
seat: &wl_seat::WlSeat,
serial: u32,
),
/// A toplevel surface requested its display state to be changed
///
@ -899,26 +899,26 @@ pub struct ShellSurfaceUserImplementation<U, R, CID, SID, SD> {
/// You are to answer with a `ToplevelConfigure` that will be sent to the client in
/// response.
pub change_display_state: fn(
evlh: &mut EventLoopHandle,
idata: &mut SID,
surface: ToplevelSurface<U, R, CID, SD>,
maximized: Option<bool>,
minimized: Option<bool>,
fullscreen: Option<bool>,
output: Option<&wl_output::WlOutput>,
evlh: &mut EventLoopHandle,
idata: &mut SID,
surface: ToplevelSurface<U, R, CID, SD>,
maximized: Option<bool>,
minimized: Option<bool>,
fullscreen: Option<bool>,
output: Option<&wl_output::WlOutput>,
) -> ToplevelConfigure,
/// The client requests the window menu to be displayed on this surface at this location
///
/// This menu belongs to the compositor. It is typically expected to contain options for
/// control of the window (maximize/minimize/close/move/etc...).
pub show_window_menu: fn(
evlh: &mut EventLoopHandle,
idata: &mut SID,
surface: ToplevelSurface<U, R, CID, SD>,
seat: &wl_seat::WlSeat,
serial: u32,
x: i32,
y: i32,
evlh: &mut EventLoopHandle,
idata: &mut SID,
surface: ToplevelSurface<U, R, CID, SD>,
seat: &wl_seat::WlSeat,
serial: u32,
x: i32,
y: i32,
),
}

View File

@ -10,10 +10,10 @@ use wayland_protocols::unstable::xdg_shell::v6::server::{zxdg_positioner_v6 as x
use wayland_server::{Client, EventLoopHandle, Resource};
use wayland_server::protocol::{wl_output, wl_shell, wl_shell_surface, wl_surface};
pub(crate) fn wl_shell_bind<U, R, CID, SID, SD>(evlh: &mut EventLoopHandle,
idata: &mut ShellSurfaceIData<U, R, CID, SID, SD>,
_: &Client, shell: wl_shell::WlShell)
where
pub(crate) fn wl_shell_bind<U, R, CID, SID, SD>(
evlh: &mut EventLoopHandle, idata: &mut ShellSurfaceIData<U, R, CID, SID, SD>, _: &Client,
shell: wl_shell::WlShell,
) where
U: 'static,
R: Role<ShellSurfaceRole> + 'static,
CID: 'static,
@ -56,8 +56,7 @@ pub fn make_shell_client<SD>(resource: &wl_shell::WlShell) -> ShellClient<SD> {
}
fn shell_implementation<U, R, CID, SID, SD>(
)
-> wl_shell::Implementation<ShellSurfaceIData<U, R, CID, SID, SD>>
) -> wl_shell::Implementation<ShellSurfaceIData<U, R, CID, SID, SD>>
where
U: 'static,
R: Role<ShellSurfaceRole> + 'static,
@ -122,9 +121,9 @@ fn destroy_shell_surface(shell_surface: &wl_shell_surface::WlShellSurface) {
::std::mem::drop(surface);
}
fn make_toplevel_handle<U, R, H, SD>(token: CompositorToken<U, R, H>,
resource: &wl_shell_surface::WlShellSurface)
-> super::ToplevelSurface<U, R, H, SD> {
fn make_toplevel_handle<U, R, H, SD>(
token: CompositorToken<U, R, H>, resource: &wl_shell_surface::WlShellSurface
) -> super::ToplevelSurface<U, R, H, SD> {
let ptr = resource.get_user_data();
let &(ref wl_surface, _) = unsafe { &*(ptr as *mut ShellSurfaceUserData) };
super::ToplevelSurface {
@ -135,9 +134,9 @@ fn make_toplevel_handle<U, R, H, SD>(token: CompositorToken<U, R, H>,
}
}
fn make_popup_handle<U, R, H, SD>(token: CompositorToken<U, R, H>,
resource: &wl_shell_surface::WlShellSurface)
-> super::PopupSurface<U, R, H, SD> {
fn make_popup_handle<U, R, H, SD>(
token: CompositorToken<U, R, H>, resource: &wl_shell_surface::WlShellSurface
) -> super::PopupSurface<U, R, H, SD> {
let ptr = resource.get_user_data();
let &(ref wl_surface, _) = unsafe { &*(ptr as *mut ShellSurfaceUserData) };
super::PopupSurface {
@ -158,12 +157,11 @@ pub fn send_popup_configure(resource: &wl_shell_surface::WlShellSurface, configu
resource.configure(wl_shell_surface::Resize::empty(), w, h);
}
fn wl_handle_display_state_change<U, R, CID, SID, SD>(evlh: &mut EventLoopHandle,
idata: &ShellSurfaceIData<U, R, CID, SID, SD>,
shell_surface: &wl_shell_surface::WlShellSurface,
maximized: Option<bool>, minimized: Option<bool>,
fullscreen: Option<bool>,
output: Option<&wl_output::WlOutput>) {
fn wl_handle_display_state_change<U, R, CID, SID, SD>(
evlh: &mut EventLoopHandle, idata: &ShellSurfaceIData<U, R, CID, SID, SD>,
shell_surface: &wl_shell_surface::WlShellSurface, maximized: Option<bool>, minimized: Option<bool>,
fullscreen: Option<bool>, output: Option<&wl_output::WlOutput>,
) {
let handle = make_toplevel_handle(idata.compositor_token, shell_surface);
// handler callback
let mut user_idata = idata.idata.borrow_mut();
@ -181,10 +179,10 @@ fn wl_handle_display_state_change<U, R, CID, SID, SD>(evlh: &mut EventLoopHandle
shell_surface.configure(wl_shell_surface::Resize::None, w, h);
}
fn wl_set_parent<U, R, CID, SID, SD>(idata: &ShellSurfaceIData<U, R, CID, SID, SD>,
shell_surface: &wl_shell_surface::WlShellSurface,
parent: Option<wl_surface::WlSurface>)
where
fn wl_set_parent<U, R, CID, SID, SD>(
idata: &ShellSurfaceIData<U, R, CID, SID, SD>, shell_surface: &wl_shell_surface::WlShellSurface,
parent: Option<wl_surface::WlSurface>,
) where
U: 'static,
R: Role<ShellSurfaceRole> + 'static,
CID: 'static,
@ -204,10 +202,10 @@ where
.unwrap();
}
fn wl_ensure_toplevel<U, R, CID, SID, SD>(evlh: &mut EventLoopHandle,
idata: &ShellSurfaceIData<U, R, CID, SID, SD>,
shell_surface: &wl_shell_surface::WlShellSurface)
where
fn wl_ensure_toplevel<U, R, CID, SID, SD>(
evlh: &mut EventLoopHandle, idata: &ShellSurfaceIData<U, R, CID, SID, SD>,
shell_surface: &wl_shell_surface::WlShellSurface,
) where
U: 'static,
R: Role<ShellSurfaceRole> + 'static,
CID: 'static,
@ -263,8 +261,7 @@ where
}
fn shell_surface_implementation<U, R, CID, SID, SD>(
)
-> wl_shell_surface::Implementation<ShellSurfaceIData<U, R, CID, SID, SD>>
) -> wl_shell_surface::Implementation<ShellSurfaceIData<U, R, CID, SID, SD>>
where
U: 'static,
R: Role<ShellSurfaceRole> + 'static,
@ -274,7 +271,8 @@ where
{
wl_shell_surface::Implementation {
pong: |evlh, idata, _, shell_surface, serial| {
let &(_, ref shell) = unsafe { &*(shell_surface.get_user_data() as *mut ShellSurfaceUserData) };
let &(_, ref shell) =
unsafe { &*(shell_surface.get_user_data() as *mut ShellSurfaceUserData) };
let valid = {
let mutex = unsafe { &*(shell.get_user_data() as *mut ShellUserData<SD>) };
let mut guard = mutex.lock().unwrap();

View File

@ -10,10 +10,10 @@ use wayland_protocols::unstable::xdg_shell::v6::server::{zxdg_popup_v6, zxdg_pos
use wayland_server::{Client, EventLoopHandle, Resource};
use wayland_server::protocol::{wl_output, wl_surface};
pub(crate) fn xdg_shell_bind<U, R, CID, SID, SD>(evlh: &mut EventLoopHandle,
idata: &mut ShellSurfaceIData<U, R, CID, SID, SD>,
_: &Client, shell: zxdg_shell_v6::ZxdgShellV6)
where
pub(crate) fn xdg_shell_bind<U, R, CID, SID, SD>(
evlh: &mut EventLoopHandle, idata: &mut ShellSurfaceIData<U, R, CID, SID, SD>, _: &Client,
shell: zxdg_shell_v6::ZxdgShellV6,
) where
U: 'static,
R: Role<ShellSurfaceRole> + 'static,
CID: 'static,
@ -53,8 +53,7 @@ pub(crate) fn make_shell_client<SD>(resource: &zxdg_shell_v6::ZxdgShellV6) -> Sh
}
fn shell_implementation<U, R, CID, SID, SD>(
)
-> zxdg_shell_v6::Implementation<ShellSurfaceIData<U, R, CID, SID, SD>>
) -> zxdg_shell_v6::Implementation<ShellSurfaceIData<U, R, CID, SID, SD>>
where
U: 'static,
R: Role<ShellSurfaceRole> + 'static,
@ -104,11 +103,10 @@ where
);
return;
}
xdg_surface.set_user_data(
Box::into_raw(Box::new((unsafe { wl_surface.clone_unchecked() }, unsafe {
shell.clone_unchecked()
}))) as *mut _,
);
xdg_surface.set_user_data(Box::into_raw(Box::new((
unsafe { wl_surface.clone_unchecked() },
unsafe { shell.clone_unchecked() },
))) as *mut _);
evlh.register(
&xdg_surface,
surface_implementation(),
@ -151,30 +149,34 @@ fn destroy_positioner(positioner: &zxdg_positioner_v6::ZxdgPositionerV6) {
fn positioner_implementation() -> zxdg_positioner_v6::Implementation<()> {
zxdg_positioner_v6::Implementation {
destroy: |_, _, _, _| {},
set_size: |_, _, _, positioner, width, height| if width < 1 || height < 1 {
positioner.post_error(
zxdg_positioner_v6::Error::InvalidInput as u32,
"Invalid size for positioner.".into(),
);
} else {
let ptr = positioner.get_user_data();
let state = unsafe { &mut *(ptr as *mut PositionerState) };
state.rect_size = (width, height);
set_size: |_, _, _, positioner, width, height| {
if width < 1 || height < 1 {
positioner.post_error(
zxdg_positioner_v6::Error::InvalidInput as u32,
"Invalid size for positioner.".into(),
);
} else {
let ptr = positioner.get_user_data();
let state = unsafe { &mut *(ptr as *mut PositionerState) };
state.rect_size = (width, height);
}
},
set_anchor_rect: |_, _, _, positioner, x, y, width, height| if width < 1 || height < 1 {
positioner.post_error(
zxdg_positioner_v6::Error::InvalidInput as u32,
"Invalid size for positioner's anchor rectangle.".into(),
);
} else {
let ptr = positioner.get_user_data();
let state = unsafe { &mut *(ptr as *mut PositionerState) };
state.anchor_rect = Rectangle {
x,
y,
width,
height,
};
set_anchor_rect: |_, _, _, positioner, x, y, width, height| {
if width < 1 || height < 1 {
positioner.post_error(
zxdg_positioner_v6::Error::InvalidInput as u32,
"Invalid size for positioner's anchor rectangle.".into(),
);
} else {
let ptr = positioner.get_user_data();
let state = unsafe { &mut *(ptr as *mut PositionerState) };
state.anchor_rect = Rectangle {
x,
y,
width,
height,
};
}
},
set_anchor: |_, _, _, positioner, anchor| {
use self::zxdg_positioner_v6::Anchor;
@ -228,15 +230,15 @@ fn destroy_surface(surface: &zxdg_surface_v6::ZxdgSurfaceV6) {
let ptr = surface.get_user_data();
surface.set_user_data(::std::ptr::null_mut());
// drop the state
let data =
unsafe { Box::from_raw(ptr as *mut (zxdg_surface_v6::ZxdgSurfaceV6, zxdg_shell_v6::ZxdgShellV6)) };
let data = unsafe {
Box::from_raw(ptr as *mut (zxdg_surface_v6::ZxdgSurfaceV6, zxdg_shell_v6::ZxdgShellV6))
};
// explicit call to drop to not forget what we're doing here
::std::mem::drop(data);
}
fn surface_implementation<U, R, CID, SID, SD>(
)
-> zxdg_surface_v6::Implementation<ShellSurfaceIData<U, R, CID, SID, SD>>
) -> zxdg_surface_v6::Implementation<ShellSurfaceIData<U, R, CID, SID, SD>>
where
U: 'static,
R: Role<ShellSurfaceRole> + 'static,
@ -417,9 +419,9 @@ fn destroy_toplevel(surface: &zxdg_toplevel_v6::ZxdgToplevelV6) {
}
// Utility functions allowing to factor out a lot of the upcoming logic
fn with_surface_toplevel_data<U, R, CID, SID, SD, F>(idata: &ShellSurfaceIData<U, R, CID, SID, SD>,
toplevel: &zxdg_toplevel_v6::ZxdgToplevelV6, f: F)
where
fn with_surface_toplevel_data<U, R, CID, SID, SD, F>(
idata: &ShellSurfaceIData<U, R, CID, SID, SD>, toplevel: &zxdg_toplevel_v6::ZxdgToplevelV6, f: F
) where
U: 'static,
R: Role<ShellSurfaceRole> + 'static,
CID: 'static,
@ -438,13 +440,11 @@ where
.expect("xdg_toplevel exists but surface has not shell_surface role?!");
}
fn xdg_handle_display_state_change<U, R, CID, SID, SD>(evlh: &mut EventLoopHandle,
idata: &ShellSurfaceIData<U, R, CID, SID, SD>,
toplevel: &zxdg_toplevel_v6::ZxdgToplevelV6,
maximized: Option<bool>, minimized: Option<bool>,
fullscreen: Option<bool>,
output: Option<&wl_output::WlOutput>)
where
fn xdg_handle_display_state_change<U, R, CID, SID, SD>(
evlh: &mut EventLoopHandle, idata: &ShellSurfaceIData<U, R, CID, SID, SD>,
toplevel: &zxdg_toplevel_v6::ZxdgToplevelV6, maximized: Option<bool>, minimized: Option<bool>,
fullscreen: Option<bool>, output: Option<&wl_output::WlOutput>,
) where
U: 'static,
R: Role<ShellSurfaceRole> + 'static,
CID: 'static,
@ -467,11 +467,10 @@ where
send_toplevel_configure(idata.compositor_token, toplevel, configure);
}
pub fn send_toplevel_configure<U, R, ID>(token: CompositorToken<U, R, ID>,
resource: &zxdg_toplevel_v6::ZxdgToplevelV6,
configure: ToplevelConfigure)
where
pub fn send_toplevel_configure<U, R, ID>(
token: CompositorToken<U, R, ID>, resource: &zxdg_toplevel_v6::ZxdgToplevelV6,
configure: ToplevelConfigure,
) where
U: 'static,
R: Role<ShellSurfaceRole> + 'static,
ID: 'static,
@ -497,9 +496,9 @@ where
.expect("xdg_toplevel exists but surface has not shell_surface role?!");
}
fn make_toplevel_handle<U, R, H, SD>(token: CompositorToken<U, R, H>,
resource: &zxdg_toplevel_v6::ZxdgToplevelV6)
-> super::ToplevelSurface<U, R, H, SD> {
fn make_toplevel_handle<U, R, H, SD>(
token: CompositorToken<U, R, H>, resource: &zxdg_toplevel_v6::ZxdgToplevelV6
) -> super::ToplevelSurface<U, R, H, SD> {
let ptr = resource.get_user_data();
let &(ref wl_surface, _, _) = unsafe { &*(ptr as *mut ShellSurfaceUserData) };
super::ToplevelSurface {
@ -511,8 +510,7 @@ fn make_toplevel_handle<U, R, H, SD>(token: CompositorToken<U, R, H>,
}
fn toplevel_implementation<U, R, CID, SID, SD>(
)
-> zxdg_toplevel_v6::Implementation<ShellSurfaceIData<U, R, CID, SID, SD>>
) -> zxdg_toplevel_v6::Implementation<ShellSurfaceIData<U, R, CID, SID, SD>>
where
U: 'static,
R: Role<ShellSurfaceRole> + 'static,
@ -546,8 +544,9 @@ where
with_surface_toplevel_data(idata, toplevel, |toplevel_data| {
toplevel_data.parent = parent.map(|toplevel_surface_parent| {
let parent_ptr = toplevel_surface_parent.get_user_data();
let &(ref parent_surface, _) =
unsafe { &*(parent_ptr as *mut (wl_surface::WlSurface, zxdg_shell_v6::ZxdgShellV6)) };
let &(ref parent_surface, _) = unsafe {
&*(parent_ptr as *mut (wl_surface::WlSurface, zxdg_shell_v6::ZxdgShellV6))
};
unsafe { parent_surface.clone_unchecked() }
})
});
@ -620,10 +619,9 @@ fn destroy_popup(surface: &zxdg_popup_v6::ZxdgPopupV6) {
::std::mem::drop(data);
}
pub(crate) fn send_popup_configure<U, R, ID>(token: CompositorToken<U, R, ID>,
resource: &zxdg_popup_v6::ZxdgPopupV6,
configure: PopupConfigure)
where
pub(crate) fn send_popup_configure<U, R, ID>(
token: CompositorToken<U, R, ID>, resource: &zxdg_popup_v6::ZxdgPopupV6, configure: PopupConfigure
) where
U: 'static,
R: Role<ShellSurfaceRole> + 'static,
ID: 'static,
@ -641,8 +639,9 @@ where
.expect("xdg_toplevel exists but surface has not shell_surface role?!");
}
fn make_popup_handle<U, R, H, SD>(token: CompositorToken<U, R, H>, resource: &zxdg_popup_v6::ZxdgPopupV6)
-> super::PopupSurface<U, R, H, SD> {
fn make_popup_handle<U, R, H, SD>(
token: CompositorToken<U, R, H>, resource: &zxdg_popup_v6::ZxdgPopupV6
) -> super::PopupSurface<U, R, H, SD> {
let ptr = resource.get_user_data();
let &(ref wl_surface, _, _) = unsafe { &*(ptr as *mut ShellSurfaceUserData) };
super::PopupSurface {
@ -654,8 +653,7 @@ fn make_popup_handle<U, R, H, SD>(token: CompositorToken<U, R, H>, resource: &zx
}
fn popup_implementation<U, R, CID, SID, SD>(
)
-> zxdg_popup_v6::Implementation<ShellSurfaceIData<U, R, CID, SID, SD>>
) -> zxdg_popup_v6::Implementation<ShellSurfaceIData<U, R, CID, SID, SD>>
where
U: 'static,
R: Role<ShellSurfaceRole> + 'static,

View File

@ -61,7 +61,6 @@
//!
//! If you are already using an handler for this signal, you probably don't want to use this handler.
use self::pool::{Pool, ResizeError};
use std::rc::Rc;
use std::sync::Arc;
@ -89,8 +88,9 @@ pub struct ShmGlobalData {
/// The global is directly registered into the eventloop, and this function
/// returns the global handle, in case you whish to remove this global in
/// the future.
pub fn init_shm_global<L>(evl: &mut EventLoop, mut formats: Vec<wl_shm::Format>, logger: L)
-> Global<wl_shm::WlShm, ShmGlobalData>
pub fn init_shm_global<L>(
evl: &mut EventLoop, mut formats: Vec<wl_shm::Format>, logger: L
) -> Global<wl_shm::WlShm, ShmGlobalData>
where
L: Into<Option<::slog::Logger>>,
{

View File

@ -1,5 +1,3 @@
use nix::{libc, unistd};
use nix::sys::mman;
use nix::sys::signal::{self, SigAction, SigHandler, Signal};