rustfmt code
This commit is contained in:
parent
b0d4bdc36d
commit
4207611e6d
|
@ -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> {
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -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",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,33 +166,35 @@ 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>>
|
||||
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 {
|
||||
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,18 +366,22 @@ 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, _| {
|
||||
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()); }
|
||||
if let &mut Some(ref mut signal) = signal {
|
||||
signal.pause(&mut evlh.state().as_proxy());
|
||||
}
|
||||
}
|
||||
notifier.active.store(false, Ordering::SeqCst);
|
||||
unsafe {
|
||||
|
@ -374,12 +394,17 @@ where
|
|||
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()); }
|
||||
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! {
|
||||
|
|
|
@ -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>> {
|
||||
|
|
|
@ -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(
|
||||
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) {
|
||||
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,26 +292,32 @@ 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| {
|
||||
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) {
|
||||
|
@ -280,12 +328,16 @@ where
|
|||
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);
|
||||
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! {
|
||||
|
|
|
@ -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() {
|
||||
egl.rent(|surface| {
|
||||
if let Some(wegl_surface) = (**surface).as_ref() {
|
||||
wegl_surface.resize(x as i32, y as i32, 0, 0)
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
{
|
||||
|
|
|
@ -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,8 +534,8 @@ 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)
|
||||
-> (
|
||||
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, ()>,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -113,8 +113,8 @@ 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)
|
||||
-> (
|
||||
evl: &mut EventLoop, name: String, physical: PhysicalProperties, logger: L
|
||||
) -> (
|
||||
StateToken<Output>,
|
||||
Global<wl_output::WlOutput, StateToken<Output>>,
|
||||
)
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -302,8 +302,8 @@ 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)
|
||||
-> (
|
||||
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>>,
|
||||
|
@ -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,11 +846,9 @@ 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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,7 +149,8 @@ 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 {
|
||||
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(),
|
||||
|
@ -160,8 +159,10 @@ fn positioner_implementation() -> zxdg_positioner_v6::Implementation<()> {
|
|||
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 {
|
||||
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(),
|
||||
|
@ -175,6 +176,7 @@ fn positioner_implementation() -> zxdg_positioner_v6::Implementation<()> {
|
|||
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,
|
||||
|
|
|
@ -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>>,
|
||||
{
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
use nix::{libc, unistd};
|
||||
use nix::sys::mman;
|
||||
use nix::sys::signal::{self, SigAction, SigHandler, Signal};
|
||||
|
|
Loading…
Reference in New Issue