rustfmt code
This commit is contained in:
parent
b0d4bdc36d
commit
4207611e6d
|
@ -60,7 +60,6 @@ rental! {
|
||||||
}
|
}
|
||||||
use self::graphics::{Graphics, Surface};
|
use self::graphics::{Graphics, Surface};
|
||||||
|
|
||||||
|
|
||||||
/// Backend based on a `DrmDevice` and a given crtc
|
/// Backend based on a `DrmDevice` and a given crtc
|
||||||
pub struct DrmBackend {
|
pub struct DrmBackend {
|
||||||
graphics: Graphics,
|
graphics: Graphics,
|
||||||
|
@ -71,9 +70,10 @@ pub struct DrmBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DrmBackend {
|
impl DrmBackend {
|
||||||
pub(crate) fn new(context: Rc<devices::Context>, crtc: crtc::Handle, mode: Mode,
|
pub(crate) fn new(
|
||||||
connectors: Vec<connector::Handle>, logger: ::slog::Logger)
|
context: Rc<devices::Context>, crtc: crtc::Handle, mode: Mode, connectors: Vec<connector::Handle>,
|
||||||
-> Result<DrmBackend> {
|
logger: ::slog::Logger,
|
||||||
|
) -> Result<DrmBackend> {
|
||||||
// logger already initialized by the DrmDevice
|
// logger already initialized by the DrmDevice
|
||||||
let log = ::slog_or_stdlog(logger);
|
let log = ::slog_or_stdlog(logger);
|
||||||
info!(log, "Initializing DrmBackend");
|
info!(log, "Initializing DrmBackend");
|
||||||
|
@ -145,9 +145,7 @@ impl DrmBackend {
|
||||||
&connectors,
|
&connectors,
|
||||||
(0, 0),
|
(0, 0),
|
||||||
Some(mode),
|
Some(mode),
|
||||||
).chain_err(
|
).chain_err(|| ErrorKind::DrmDev(format!("{:?}", context.devices.drm)))?;
|
||||||
|| ErrorKind::DrmDev(format!("{:?}", context.devices.drm)),
|
|
||||||
)?;
|
|
||||||
front_bo.set_userdata(fb);
|
front_bo.set_userdata(fb);
|
||||||
|
|
||||||
Ok(EGL {
|
Ok(EGL {
|
||||||
|
@ -193,9 +191,7 @@ impl DrmBackend {
|
||||||
/// Errors if the new connector does not support the currently set `Mode`
|
/// Errors if the new connector does not support the currently set `Mode`
|
||||||
pub fn add_connector(&mut self, connector: connector::Handle) -> Result<()> {
|
pub fn add_connector(&mut self, connector: connector::Handle) -> Result<()> {
|
||||||
let info = connector::Info::load_from_device(self.graphics.head().head().head(), connector)
|
let info = connector::Info::load_from_device(self.graphics.head().head().head(), connector)
|
||||||
.chain_err(|| {
|
.chain_err(|| ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head())))?;
|
||||||
ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head()))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// check if the connector can handle the current mode
|
// check if the connector can handle the current mode
|
||||||
if info.modes().contains(&self.mode) {
|
if info.modes().contains(&self.mode) {
|
||||||
|
@ -203,9 +199,8 @@ impl DrmBackend {
|
||||||
let encoders = info.encoders()
|
let encoders = info.encoders()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|encoder| {
|
.map(|encoder| {
|
||||||
encoder::Info::load_from_device(self.graphics.head().head().head(), *encoder).chain_err(
|
encoder::Info::load_from_device(self.graphics.head().head().head(), *encoder)
|
||||||
|| ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head())),
|
.chain_err(|| ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head())))
|
||||||
)
|
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<encoder::Info>>>()?;
|
.collect::<Result<Vec<encoder::Info>>>()?;
|
||||||
|
|
||||||
|
@ -215,9 +210,7 @@ impl DrmBackend {
|
||||||
.head()
|
.head()
|
||||||
.head()
|
.head()
|
||||||
.resource_handles()
|
.resource_handles()
|
||||||
.chain_err(|| {
|
.chain_err(|| ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head())))?;
|
||||||
ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head()))
|
|
||||||
})?;
|
|
||||||
if !encoders
|
if !encoders
|
||||||
.iter()
|
.iter()
|
||||||
.map(|encoder| encoder.possible_crtcs())
|
.map(|encoder| encoder.possible_crtcs())
|
||||||
|
@ -272,9 +265,7 @@ impl DrmBackend {
|
||||||
// check the connectors
|
// check the connectors
|
||||||
for connector in &self.connectors {
|
for connector in &self.connectors {
|
||||||
if !connector::Info::load_from_device(self.graphics.head().head().head(), *connector)
|
if !connector::Info::load_from_device(self.graphics.head().head().head(), *connector)
|
||||||
.chain_err(|| {
|
.chain_err(|| ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head())))?
|
||||||
ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head()))
|
|
||||||
})?
|
|
||||||
.modes()
|
.modes()
|
||||||
.contains(&mode)
|
.contains(&mode)
|
||||||
{
|
{
|
||||||
|
@ -295,9 +286,7 @@ impl DrmBackend {
|
||||||
// resolution.
|
// resolution.
|
||||||
debug!(
|
debug!(
|
||||||
logger_ref,
|
logger_ref,
|
||||||
"Reinitializing surface for new mode: {}:{}",
|
"Reinitializing surface for new mode: {}:{}", w, h
|
||||||
w,
|
|
||||||
h
|
|
||||||
);
|
);
|
||||||
graphics.gbm.surface = Surface::try_new(
|
graphics.gbm.surface = Surface::try_new(
|
||||||
{
|
{
|
||||||
|
@ -340,9 +329,8 @@ impl DrmBackend {
|
||||||
front_bo.format()
|
front_bo.format()
|
||||||
);
|
);
|
||||||
// we need a framebuffer per front_buffer
|
// we need a framebuffer per front_buffer
|
||||||
let fb = framebuffer::create(graphics.context.devices.drm, &*front_bo).chain_err(|| {
|
let fb = framebuffer::create(graphics.context.devices.drm, &*front_bo)
|
||||||
ErrorKind::DrmDev(format!("{:?}", graphics.context.devices.drm))
|
.chain_err(|| ErrorKind::DrmDev(format!("{:?}", graphics.context.devices.drm)))?;
|
||||||
})?;
|
|
||||||
|
|
||||||
debug!(logger_ref, "Initialize screen");
|
debug!(logger_ref, "Initialize screen");
|
||||||
crtc::set(
|
crtc::set(
|
||||||
|
@ -352,9 +340,7 @@ impl DrmBackend {
|
||||||
connectors_ref,
|
connectors_ref,
|
||||||
(0, 0),
|
(0, 0),
|
||||||
Some(mode),
|
Some(mode),
|
||||||
).chain_err(|| {
|
).chain_err(|| ErrorKind::DrmDev(format!("{:?}", graphics.context.devices.drm)))?;
|
||||||
ErrorKind::DrmDev(format!("{:?}", graphics.context.devices.drm))
|
|
||||||
})?;
|
|
||||||
front_bo.set_userdata(fb);
|
front_bo.set_userdata(fb);
|
||||||
|
|
||||||
Ok(EGL {
|
Ok(EGL {
|
||||||
|
@ -424,13 +410,12 @@ impl GraphicsBackend for DrmBackend {
|
||||||
self.graphics.head().head().head(),
|
self.graphics.head().head().head(),
|
||||||
self.crtc,
|
self.crtc,
|
||||||
(x as i32, y as i32),
|
(x as i32, y as i32),
|
||||||
).chain_err(|| {
|
).chain_err(|| ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head())))
|
||||||
ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head()))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_cursor_representation(&self, buffer: &ImageBuffer<Rgba<u8>, Vec<u8>>, hotspot: (u32, u32))
|
fn set_cursor_representation(
|
||||||
-> Result<()> {
|
&self, buffer: &ImageBuffer<Rgba<u8>, Vec<u8>>, hotspot: (u32, u32)
|
||||||
|
) -> Result<()> {
|
||||||
let (w, h) = buffer.dimensions();
|
let (w, h) = buffer.dimensions();
|
||||||
|
|
||||||
debug!(self.logger, "Importing cursor");
|
debug!(self.logger, "Importing cursor");
|
||||||
|
@ -463,9 +448,9 @@ impl GraphicsBackend for DrmBackend {
|
||||||
(hotspot.0 as i32, hotspot.1 as i32),
|
(hotspot.0 as i32, hotspot.1 as i32),
|
||||||
).is_err()
|
).is_err()
|
||||||
{
|
{
|
||||||
crtc::set_cursor(self.graphics.head().head().head(), self.crtc, &cursor).chain_err(|| {
|
crtc::set_cursor(self.graphics.head().head().head(), self.crtc, &cursor).chain_err(
|
||||||
ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head()))
|
|| ErrorKind::DrmDev(format!("{:?}", self.graphics.head().head().head())),
|
||||||
})?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// and store it
|
// and store it
|
||||||
|
@ -498,7 +483,10 @@ impl EGLGraphicsBackend for DrmBackend {
|
||||||
// would most likely result in a lot of flickering.
|
// would most likely result in a lot of flickering.
|
||||||
// neither weston, wlc or wlroots bother with that as well.
|
// neither weston, wlc or wlroots bother with that as well.
|
||||||
// so we just assume we got at least two buffers to do flipping
|
// 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
|
// create a framebuffer if the front buffer does not have one already
|
||||||
// (they are reused by gbm)
|
// (they are reused by gbm)
|
||||||
|
@ -506,7 +494,8 @@ impl EGLGraphicsBackend for DrmBackend {
|
||||||
let fb = if let Some(info) = maybe_fb {
|
let fb = if let Some(info) = maybe_fb {
|
||||||
info
|
info
|
||||||
} else {
|
} 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);
|
next_bo.set_userdata(fb);
|
||||||
fb
|
fb
|
||||||
};
|
};
|
||||||
|
@ -515,7 +504,12 @@ impl EGLGraphicsBackend for DrmBackend {
|
||||||
trace!(self.logger, "Queueing Page flip");
|
trace!(self.logger, "Queueing Page flip");
|
||||||
|
|
||||||
// and 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 {
|
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> {
|
unsafe fn make_current(&self) -> ::std::result::Result<(), SwapBuffersError> {
|
||||||
|
|
|
@ -188,9 +188,9 @@
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use backend::graphics::egl::{EGLContext, GlAttributes, PixelFormatRequirements};
|
use backend::graphics::egl::{EGLContext, GlAttributes, PixelFormatRequirements};
|
||||||
|
use backend::graphics::egl::EGLGraphicsBackend;
|
||||||
#[cfg(feature = "backend_session")]
|
#[cfg(feature = "backend_session")]
|
||||||
use backend::session::SessionObserver;
|
use backend::session::SessionObserver;
|
||||||
use backend::graphics::egl::EGLGraphicsBackend;
|
|
||||||
use drm::Device as BasicDevice;
|
use drm::Device as BasicDevice;
|
||||||
use drm::control::{connector, crtc, encoder, Mode, ResourceInfo};
|
use drm::control::{connector, crtc, encoder, Mode, ResourceInfo};
|
||||||
use drm::control::Device as ControlDevice;
|
use drm::control::Device as ControlDevice;
|
||||||
|
@ -204,11 +204,11 @@ use std::collections::HashMap;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::io::Result as IoResult;
|
use std::io::Result as IoResult;
|
||||||
use std::os::unix::io::{IntoRawFd, AsRawFd, RawFd};
|
|
||||||
use std::rc::Rc;
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
|
||||||
|
use std::rc::Rc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use wayland_server::{EventLoopHandle, StateToken, StateProxy};
|
use wayland_server::{EventLoopHandle, StateProxy, StateToken};
|
||||||
use wayland_server::sources::{FdEventSource, FdEventSourceImpl, FdInterest};
|
use wayland_server::sources::{FdEventSource, FdEventSourceImpl, FdInterest};
|
||||||
|
|
||||||
mod backend;
|
mod backend;
|
||||||
|
@ -369,25 +369,21 @@ impl<B: From<DrmBackend> + Borrow<DrmBackend> + 'static> DrmDevice<B> {
|
||||||
|
|
||||||
let mut old_state = HashMap::new();
|
let mut old_state = HashMap::new();
|
||||||
let res_handles = drm.resource_handles()
|
let res_handles = drm.resource_handles()
|
||||||
.chain_err(|| {
|
.chain_err(|| ErrorKind::DrmDev(format!("Loading drm resources on {:?}", drm)))?;
|
||||||
ErrorKind::DrmDev(format!("Loading drm resources on {:?}", drm))
|
|
||||||
})?;
|
|
||||||
for &con in res_handles.connectors() {
|
for &con in res_handles.connectors() {
|
||||||
let con_info = connector::Info::load_from_device(&drm, con)
|
let con_info = connector::Info::load_from_device(&drm, con)
|
||||||
.chain_err(|| {
|
.chain_err(|| ErrorKind::DrmDev(format!("Loading connector info on {:?}", drm)))?;
|
||||||
ErrorKind::DrmDev(format!("Loading connector info on {:?}", drm))
|
|
||||||
})?;
|
|
||||||
if let Some(enc) = con_info.current_encoder() {
|
if let Some(enc) = con_info.current_encoder() {
|
||||||
let enc_info = encoder::Info::load_from_device(&drm, enc)
|
let enc_info = encoder::Info::load_from_device(&drm, enc)
|
||||||
.chain_err(|| {
|
.chain_err(|| ErrorKind::DrmDev(format!("Loading encoder info on {:?}", drm)))?;
|
||||||
ErrorKind::DrmDev(format!("Loading encoder info on {:?}", drm))
|
|
||||||
})?;
|
|
||||||
if let Some(crtc) = enc_info.current_crtc() {
|
if let Some(crtc) = enc_info.current_crtc() {
|
||||||
let info = crtc::Info::load_from_device(&drm, crtc)
|
let info = crtc::Info::load_from_device(&drm, crtc)
|
||||||
.chain_err(|| {
|
.chain_err(|| ErrorKind::DrmDev(format!("Loading crtc info on {:?}", drm)))?;
|
||||||
ErrorKind::DrmDev(format!("Loading crtc info on {:?}", drm))
|
old_state
|
||||||
})?;
|
.entry(crtc)
|
||||||
old_state.entry(crtc).or_insert((info, Vec::new())).1.push(con);
|
.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
|
/// Errors if initialization fails or the mode is not available on all given
|
||||||
/// connectors.
|
/// connectors.
|
||||||
pub fn create_backend<'a, I, S>(&mut self, state: S, crtc: crtc::Handle, mode: Mode, connectors: I)
|
pub fn create_backend<'a, I, S>(
|
||||||
-> Result<&StateToken<B>>
|
&mut self, state: S, crtc: crtc::Handle, mode: Mode, connectors: I
|
||||||
|
) -> Result<&StateToken<B>>
|
||||||
where
|
where
|
||||||
I: Into<Vec<connector::Handle>>,
|
I: Into<Vec<connector::Handle>>,
|
||||||
S: Into<StateProxy<'a>>,
|
S: Into<StateProxy<'a>>,
|
||||||
|
@ -447,7 +444,10 @@ impl<B: From<DrmBackend> + Borrow<DrmBackend> + 'static> DrmDevice<B> {
|
||||||
for connector in &connectors {
|
for connector in &connectors {
|
||||||
let con_info = connector::Info::load_from_device(self.context.head().head(), *connector)
|
let con_info = connector::Info::load_from_device(self.context.head().head(), *connector)
|
||||||
.chain_err(|| {
|
.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
|
// check the mode
|
||||||
|
@ -461,21 +461,26 @@ impl<B: From<DrmBackend> + Borrow<DrmBackend> + 'static> DrmDevice<B> {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|encoder| {
|
.map(|encoder| {
|
||||||
encoder::Info::load_from_device(self.context.head().head(), *encoder).chain_err(|| {
|
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>>>()?;
|
.collect::<Result<Vec<encoder::Info>>>()?;
|
||||||
|
|
||||||
// and if any encoder supports the selected crtc
|
// and if any encoder supports the selected crtc
|
||||||
let resource_handles = self.resource_handles().chain_err(|| {
|
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
|
if !encoders
|
||||||
.iter()
|
.iter()
|
||||||
.map(|encoder| encoder.possible_crtcs())
|
.map(|encoder| encoder.possible_crtcs())
|
||||||
.any(|crtc_list| {
|
.any(|crtc_list| resource_handles.filter_crtcs(crtc_list).contains(&crtc))
|
||||||
resource_handles.filter_crtcs(crtc_list).contains(&crtc)
|
{
|
||||||
}) {
|
|
||||||
bail!(ErrorKind::NoSuitableEncoder(con_info, 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 logger = self.logger.new(o!("crtc" => format!("{:?}", crtc)));
|
||||||
let backend = DrmBackend::new(self.context.clone(), crtc, mode, connectors, logger)?;
|
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())
|
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
|
/// Panics if the backend is already borrowed from the state
|
||||||
pub fn destroy_backend<'a, S>(&mut self, state: S, crtc: &crtc::Handle)
|
pub fn destroy_backend<'a, S>(&mut self, state: S, crtc: &crtc::Handle)
|
||||||
where
|
where
|
||||||
S: Into<StateProxy<'a>>
|
S: Into<StateProxy<'a>>,
|
||||||
{
|
{
|
||||||
if let Some(token) = self.backends.remove(crtc) {
|
if let Some(token) = self.backends.remove(crtc) {
|
||||||
state.into().remove(token);
|
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");
|
panic!("Pending DrmBackends. Please free all backends before the DrmDevice gets destroyed");
|
||||||
}
|
}
|
||||||
for (handle, (info, connectors)) in self.old_state.drain() {
|
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()) {
|
if let Err(err) = crtc::set(
|
||||||
error!(self.logger, "Failed to reset crtc ({:?}). Error: {}", handle, err);
|
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() {
|
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
|
/// ## Panics
|
||||||
/// The device is already borrowed from the given `state`. Borrowing it again will panic
|
/// 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.
|
/// 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>,
|
fn ready<'a, S: Into<StateProxy<'a>>>(
|
||||||
crtc: crtc::Handle, frame: u32, duration: Duration);
|
&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 `DrmDevice` has thrown an error.
|
||||||
///
|
///
|
||||||
/// The related backends are most likely *not* usable anymore and
|
/// 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`,
|
/// Bind a `DrmDevice` to an `EventLoop`,
|
||||||
///
|
///
|
||||||
/// This will cause it to recieve events and feed them into an `DrmHandler`
|
/// 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)
|
pub fn drm_device_bind<B, H>(
|
||||||
-> IoResult<FdEventSource<(StateToken<DrmDevice<B>>, H)>>
|
evlh: &mut EventLoopHandle, device: StateToken<DrmDevice<B>>, handler: H
|
||||||
|
) -> IoResult<FdEventSource<(StateToken<DrmDevice<B>>, H)>>
|
||||||
where
|
where
|
||||||
B: From<DrmBackend> + Borrow<DrmBackend> + 'static,
|
B: From<DrmBackend> + Borrow<DrmBackend> + 'static,
|
||||||
H: DrmHandler<B> + 'static,
|
H: DrmHandler<B> + 'static,
|
||||||
|
@ -624,13 +646,22 @@ where
|
||||||
state.get(&backend_token).borrow().unlock_buffer();
|
state.get(&backend_token).borrow().unlock_buffer();
|
||||||
trace!(logger, "Handling event for backend {:?}", event.crtc);
|
trace!(logger, "Handling event for backend {:?}", event.crtc);
|
||||||
// and then call the user to render the next frame
|
// 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| {
|
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);
|
let device: &mut DrmDevice<B> = state.get_mut(self);
|
||||||
device.active = false;
|
device.active = false;
|
||||||
if let Err(err) = device.drop_master() {
|
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| {
|
state.with_value(self, |state, device| {
|
||||||
device.active = true;
|
device.active = true;
|
||||||
if let Err(err) = device.set_master() {
|
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() {
|
for token in device.backends.values() {
|
||||||
let backend = state.get(token);
|
let backend = state.get(token);
|
||||||
if let Err(err) = backend.borrow().swap_buffers() {
|
if let Err(err) = backend.borrow().swap_buffers() {
|
||||||
// TODO handle this better?
|
// 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, ()> {
|
impl<'a> EGLContext<'a, ()> {
|
||||||
/// Create a new context from a given `winit`-`Window`
|
/// Create a new context from a given `winit`-`Window`
|
||||||
#[cfg(feature = "backend_winit")]
|
#[cfg(feature = "backend_winit")]
|
||||||
pub fn new_from_winit<L>(window: &'a WinitWindow, attributes: GlAttributes,
|
pub fn new_from_winit<L>(
|
||||||
reqs: PixelFormatRequirements, logger: L)
|
window: &'a WinitWindow, attributes: GlAttributes, reqs: PixelFormatRequirements, logger: L
|
||||||
-> Result<EGLContext<'a, WinitWindow>>
|
) -> Result<EGLContext<'a, WinitWindow>>
|
||||||
where
|
where
|
||||||
L: Into<Option<::slog::Logger>>,
|
L: Into<Option<::slog::Logger>>,
|
||||||
{
|
{
|
||||||
|
@ -268,9 +268,9 @@ impl<'a> EGLContext<'a, ()> {
|
||||||
|
|
||||||
/// Create a new context from a given `gbm::Device`
|
/// Create a new context from a given `gbm::Device`
|
||||||
#[cfg(feature = "backend_drm")]
|
#[cfg(feature = "backend_drm")]
|
||||||
pub fn new_from_gbm<L, U: 'static>(gbm: &'a GbmDevice<'a>, attributes: GlAttributes,
|
pub fn new_from_gbm<L, U: 'static>(
|
||||||
reqs: PixelFormatRequirements, logger: L)
|
gbm: &'a GbmDevice<'a>, attributes: GlAttributes, reqs: PixelFormatRequirements, logger: L
|
||||||
-> Result<EGLContext<'a, GbmSurface<'a, U>>>
|
) -> Result<EGLContext<'a, GbmSurface<'a, U>>>
|
||||||
where
|
where
|
||||||
L: Into<Option<::slog::Logger>>,
|
L: Into<Option<::slog::Logger>>,
|
||||||
{
|
{
|
||||||
|
@ -288,9 +288,10 @@ impl<'a> EGLContext<'a, ()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: NativeSurface> EGLContext<'a, T> {
|
impl<'a, T: NativeSurface> EGLContext<'a, T> {
|
||||||
unsafe fn new(native: NativeDisplayPtr, mut attributes: GlAttributes, reqs: PixelFormatRequirements,
|
unsafe fn new(
|
||||||
log: ::slog::Logger)
|
native: NativeDisplayPtr, mut attributes: GlAttributes, reqs: PixelFormatRequirements,
|
||||||
-> Result<EGLContext<'a, T>>
|
log: ::slog::Logger,
|
||||||
|
) -> Result<EGLContext<'a, T>>
|
||||||
where
|
where
|
||||||
T: NativeSurface,
|
T: NativeSurface,
|
||||||
{
|
{
|
||||||
|
@ -322,8 +323,7 @@ impl<'a, T: NativeSurface> EGLContext<'a, T> {
|
||||||
Some(version) => {
|
Some(version) => {
|
||||||
error!(
|
error!(
|
||||||
log,
|
log,
|
||||||
"OpenGLES {:?} is unknown and not supported by the EGL renderer backend",
|
"OpenGLES {:?} is unknown and not supported by the EGL renderer backend", version
|
||||||
version
|
|
||||||
);
|
);
|
||||||
bail!(ErrorKind::OpenGlVersionNotSupported(version));
|
bail!(ErrorKind::OpenGlVersionNotSupported(version));
|
||||||
}
|
}
|
||||||
|
@ -423,9 +423,9 @@ impl<'a, T: NativeSurface> EGLContext<'a, T> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeDisplayPtr::X11(display) |
|
NativeDisplayPtr::X11(display)
|
||||||
NativeDisplayPtr::Gbm(display) |
|
| NativeDisplayPtr::Gbm(display)
|
||||||
NativeDisplayPtr::Wayland(display) => {
|
| NativeDisplayPtr::Wayland(display) => {
|
||||||
trace!(log, "Default EGL Display Initialization via GetDisplay");
|
trace!(log, "Default EGL Display Initialization via GetDisplay");
|
||||||
egl.GetDisplay(display as *mut _)
|
egl.GetDisplay(display as *mut _)
|
||||||
}
|
}
|
||||||
|
@ -727,9 +727,9 @@ impl<'a, T: NativeSurface> EGLContext<'a, T> {
|
||||||
self.display,
|
self.display,
|
||||||
self.config_id,
|
self.config_id,
|
||||||
match surface {
|
match surface {
|
||||||
NativeSurfacePtr::X11(ptr) |
|
NativeSurfacePtr::X11(ptr)
|
||||||
NativeSurfacePtr::Wayland(ptr) |
|
| NativeSurfacePtr::Wayland(ptr)
|
||||||
NativeSurfacePtr::Gbm(ptr) => ptr,
|
| NativeSurfacePtr::Gbm(ptr) => ptr,
|
||||||
},
|
},
|
||||||
self.surface_attributes.as_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.
|
/// Returns true if the OpenGL surface is the current one in the thread.
|
||||||
pub fn is_current(&self) -> bool {
|
pub fn is_current(&self) -> bool {
|
||||||
unsafe { self.context.egl.GetCurrentSurface(ffi::egl::DRAW as _) == self.surface as *const _ &&
|
unsafe {
|
||||||
self.context.egl.GetCurrentSurface(ffi::egl::READ as _) == self.surface as *const _ }
|
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::ContextLost => "The context has been lost, it needs to be recreated",
|
||||||
SwapBuffersError::AlreadySwapped => {
|
SwapBuffersError::AlreadySwapped => {
|
||||||
"Buffers are already swapped, swap_buffers was called too many times"
|
"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
|
/// 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
|
/// 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.
|
/// void type () to represent no possible customization of the cursor itself.
|
||||||
fn set_cursor_representation(&self, cursor: &Self::CursorFormat, hotspot: (u32, u32))
|
fn set_cursor_representation(
|
||||||
-> Result<(), Self::Error>;
|
&self, cursor: &Self::CursorFormat, hotspot: (u32, u32)
|
||||||
|
) -> Result<(), Self::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod software;
|
pub mod software;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
//! Common traits and types used for software rendering on graphics backends
|
//! Common traits and types used for software rendering on graphics backends
|
||||||
|
|
||||||
|
|
||||||
use super::GraphicsBackend;
|
use super::GraphicsBackend;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use wayland_server::protocol::wl_shm::Format;
|
use wayland_server::protocol::wl_shm::Format;
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
//! Implementation of input backend trait for types provided by `libinput`
|
//! Implementation of input backend trait for types provided by `libinput`
|
||||||
|
|
||||||
|
use backend::input as backend;
|
||||||
#[cfg(feature = "backend_session")]
|
#[cfg(feature = "backend_session")]
|
||||||
use backend::session::{AsErrno, Session, SessionObserver};
|
use backend::session::{AsErrno, Session, SessionObserver};
|
||||||
use backend::input as backend;
|
|
||||||
use input as libinput;
|
use input as libinput;
|
||||||
use input::event;
|
use input::event;
|
||||||
use std::collections::hash_map::{DefaultHasher, Entry, HashMap};
|
use std::collections::hash_map::{DefaultHasher, Entry, HashMap};
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::io::{Error as IoError, Result as IoResult};
|
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::os::unix::io::RawFd;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::rc::Rc;
|
||||||
use wayland_server::{EventLoopHandle, StateProxy};
|
use wayland_server::{EventLoopHandle, StateProxy};
|
||||||
use wayland_server::sources::{FdEventSource, FdEventSourceImpl, FdInterest};
|
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> {
|
impl<S: Session> libinput::LibinputInterface for LibinputSessionInterface<S> {
|
||||||
fn open_restricted(&mut self, path: &Path, flags: i32) -> Result<RawFd, i32> {
|
fn open_restricted(&mut self, path: &Path, flags: i32) -> Result<RawFd, i32> {
|
||||||
use nix::fcntl::OFlag;
|
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) {
|
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
|
/// Automatically feeds the backend with incoming events without any manual calls to
|
||||||
/// `dispatch_new_events`. Should be used to achieve the smallest possible latency.
|
/// `dispatch_new_events`. Should be used to achieve the smallest possible latency.
|
||||||
pub fn libinput_bind(backend: LibinputInputBackend, evlh: &mut EventLoopHandle)
|
pub fn libinput_bind(
|
||||||
-> IoResult<FdEventSource<LibinputInputBackend>>
|
backend: LibinputInputBackend, evlh: &mut EventLoopHandle
|
||||||
{
|
) -> IoResult<FdEventSource<LibinputInputBackend>> {
|
||||||
let fd = unsafe { backend.context.fd() };
|
let fd = unsafe { backend.context.fd() };
|
||||||
evlh.add_fd_event_source(
|
evlh.add_fd_event_source(
|
||||||
fd,
|
fd,
|
||||||
|
@ -610,13 +612,13 @@ pub fn libinput_bind(backend: LibinputInputBackend, evlh: &mut EventLoopHandle)
|
||||||
fn fd_event_source_implementation() -> FdEventSourceImpl<LibinputInputBackend> {
|
fn fd_event_source_implementation() -> FdEventSourceImpl<LibinputInputBackend> {
|
||||||
FdEventSourceImpl {
|
FdEventSourceImpl {
|
||||||
ready: |_evlh, ref mut backend, _, _| {
|
ready: |_evlh, ref mut backend, _, _| {
|
||||||
use ::backend::input::InputBackend;
|
use backend::input::InputBackend;
|
||||||
if let Err(error) = backend.dispatch_new_events() {
|
if let Err(error) = backend.dispatch_new_events() {
|
||||||
warn!(backend.logger, "Libinput errored: {}", error);
|
warn!(backend.logger, "Libinput errored: {}", error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: |_evlh, ref backend, _, error| {
|
error: |_evlh, ref backend, _, error| {
|
||||||
warn!(backend.logger, "Libinput fd errored: {}", error);
|
warn!(backend.logger, "Libinput fd errored: {}", error);
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,24 +46,22 @@
|
||||||
//! automatically by the `UdevBackend`, if not done manually).
|
//! automatically by the `UdevBackend`, if not done manually).
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use std::io::Result as IoResult;
|
use super::{AsErrno, Session, SessionNotifier, SessionObserver};
|
||||||
use std::path::Path;
|
|
||||||
use std::os::unix::io::RawFd;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
|
||||||
use nix::{Error as NixError, Result as NixResult};
|
use nix::{Error as NixError, Result as NixResult};
|
||||||
use nix::fcntl::{self, open, OFlag};
|
use nix::fcntl::{self, open, OFlag};
|
||||||
use nix::libc::c_int;
|
use nix::libc::c_int;
|
||||||
use nix::sys::signal::{self, Signal};
|
use nix::sys::signal::{self, Signal};
|
||||||
use nix::sys::stat::{dev_t, major, minor, Mode, fstat};
|
use nix::sys::stat::{dev_t, fstat, major, minor, Mode};
|
||||||
use nix::unistd::{dup, close};
|
use nix::unistd::{close, dup};
|
||||||
use wayland_server::EventLoopHandle;
|
use std::io::Result as IoResult;
|
||||||
use wayland_server::sources::SignalEventSource;
|
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")]
|
#[cfg(feature = "backend_session_udev")]
|
||||||
use udev::Context;
|
use udev::Context;
|
||||||
|
use wayland_server::EventLoopHandle;
|
||||||
use super::{AsErrno, Session, SessionNotifier, SessionObserver};
|
use wayland_server::sources::SignalEventSource;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
mod tty {
|
mod tty {
|
||||||
|
@ -102,7 +100,7 @@ mod tty {
|
||||||
pub const VT_PROCESS: i8 = 0x01;
|
pub const VT_PROCESS: i8 = 0x01;
|
||||||
pub const VT_ACKACQ: i32 = 0x02;
|
pub const VT_ACKACQ: i32 = 0x02;
|
||||||
|
|
||||||
extern {
|
extern "C" {
|
||||||
pub fn __libc_current_sigrtmin() -> i8;
|
pub fn __libc_current_sigrtmin() -> i8;
|
||||||
pub fn __libc_current_sigrtmax() -> 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
|
major(dev) == TTY_MAJOR
|
||||||
};
|
};
|
||||||
res || minor(dev) != 0
|
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.
|
/// 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)>
|
pub fn new<L>(tty: Option<&Path>, logger: L) -> Result<(DirectSession, DirectSessionNotifier)>
|
||||||
where
|
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
|
let fd = tty.map(|path| {
|
||||||
.map(|path| open(path, fcntl::O_RDWR | fcntl::O_CLOEXEC, Mode::empty())
|
open(path, fcntl::O_RDWR | fcntl::O_CLOEXEC, Mode::empty())
|
||||||
.chain_err(|| ErrorKind::FailedToOpenTTY(String::from(path.to_string_lossy()))))
|
.chain_err(|| ErrorKind::FailedToOpenTTY(String::from(path.to_string_lossy())))
|
||||||
.unwrap_or(dup(0 /*stdin*/).chain_err(|| ErrorKind::FailedToOpenTTY(String::from("<stdin>"))))?;
|
}).unwrap_or(dup(0 /*stdin*/).chain_err(|| ErrorKind::FailedToOpenTTY(String::from("<stdin>"))))?;
|
||||||
|
|
||||||
let active = Arc::new(AtomicBool::new(true));
|
let active = Arc::new(AtomicBool::new(true));
|
||||||
|
|
||||||
match DirectSession::setup_tty(tty, fd, logger.clone()) {
|
match DirectSession::setup_tty(tty, fd, logger.clone()) {
|
||||||
Ok((vt, old_keyboard_mode, signal)) => {
|
Ok((vt, old_keyboard_mode, signal)) => Ok((
|
||||||
Ok((DirectSession {
|
DirectSession {
|
||||||
tty: fd,
|
tty: fd,
|
||||||
active: active.clone(),
|
active: active.clone(),
|
||||||
vt,
|
vt,
|
||||||
old_keyboard_mode,
|
old_keyboard_mode,
|
||||||
logger: logger.new(o!("vt" => format!("{}", vt), "component" => "session")),
|
logger: logger.new(o!("vt" => format!("{}", vt), "component" => "session")),
|
||||||
}, DirectSessionNotifier {
|
},
|
||||||
|
DirectSessionNotifier {
|
||||||
tty: fd,
|
tty: fd,
|
||||||
active,
|
active,
|
||||||
signals: Vec::new(),
|
signals: Vec::new(),
|
||||||
signal,
|
signal,
|
||||||
logger: logger.new(o!("vt" => format!("{}", vt), "component" => "session_notifier"))
|
logger: logger.new(o!("vt" => format!("{}", vt), "component" => "session_notifier")),
|
||||||
}))
|
},
|
||||||
},
|
)),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let _ = close(fd);
|
let _ = close(fd);
|
||||||
Err(err)
|
Err(err)
|
||||||
|
@ -226,9 +226,11 @@ impl DirectSession {
|
||||||
|
|
||||||
let mut old_keyboard_mode = 0;
|
let mut old_keyboard_mode = 0;
|
||||||
unsafe {
|
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_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
|
// TODO: Support realtime signals
|
||||||
|
@ -305,19 +307,33 @@ impl Drop for DirectSession {
|
||||||
info!(self.logger, "Deallocating tty {}", self.tty);
|
info!(self.logger, "Deallocating tty {}", self.tty);
|
||||||
|
|
||||||
if let Err(err) = unsafe { tty::kd_set_kb_mode(self.tty, self.old_keyboard_mode) } {
|
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) } {
|
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 {
|
||||||
mode: tty::VT_AUTO,
|
tty::vt_set_mode(
|
||||||
..Default::default()
|
self.tty,
|
||||||
}) } {
|
&tty::VtMode {
|
||||||
|
mode: tty::VT_AUTO,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
} {
|
||||||
error!(self.logger, "Failed to reset vt handling. Error: {}", err);
|
error!(self.logger, "Failed to reset vt handling. Error: {}", err);
|
||||||
}
|
}
|
||||||
if let Err(err) = close(self.tty) {
|
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.
|
/// 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
|
/// If you don't use this function `DirectSessionNotifier` will not correctly tell you the current
|
||||||
/// session state.
|
/// session state.
|
||||||
pub fn direct_session_bind<L>(notifier: DirectSessionNotifier, evlh: &mut EventLoopHandle, _logger: L)
|
pub fn direct_session_bind<L>(
|
||||||
-> IoResult<SignalEventSource<DirectSessionNotifier>>
|
notifier: DirectSessionNotifier, evlh: &mut EventLoopHandle, _logger: L
|
||||||
|
) -> IoResult<SignalEventSource<DirectSessionNotifier>>
|
||||||
where
|
where
|
||||||
L: Into<Option<::slog::Logger>>,
|
L: Into<Option<::slog::Logger>>,
|
||||||
{
|
{
|
||||||
let signal = notifier.signal;
|
let signal = notifier.signal;
|
||||||
|
|
||||||
evlh.add_signal_event_source(|evlh, notifier, _| {
|
evlh.add_signal_event_source(
|
||||||
if notifier.is_active() {
|
|evlh, notifier, _| {
|
||||||
info!(notifier.logger, "Session shall become inactive");
|
if notifier.is_active() {
|
||||||
for signal in &mut notifier.signals {
|
info!(notifier.logger, "Session shall become inactive");
|
||||||
if let &mut Some(ref mut signal) = signal {signal.pause(&mut evlh.state().as_proxy()); }
|
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 {
|
notifier,
|
||||||
tty::vt_rel_disp(notifier.tty, 1).expect("Unable to release tty lock");
|
signal,
|
||||||
}
|
)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error_chain! {
|
error_chain! {
|
||||||
|
|
|
@ -10,12 +10,12 @@
|
||||||
//! The following mechanisms are currently provided:
|
//! The following mechanisms are currently provided:
|
||||||
//! - direct - legacy tty / virtual terminal kernel api
|
//! - direct - legacy tty / virtual terminal kernel api
|
||||||
//!
|
//!
|
||||||
use std::path::Path;
|
use nix::fcntl::OFlag;
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
use std::rc::Rc;
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::os::unix::io::RawFd;
|
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;
|
use wayland_server::StateProxy;
|
||||||
|
|
||||||
/// General session interface.
|
/// General session interface.
|
||||||
|
@ -83,13 +83,23 @@ pub trait SessionObserver {
|
||||||
impl Session for () {
|
impl Session for () {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
fn open(&mut self, _path: &Path, _flags: OFlag) -> Result<RawFd, Self::Error> { Err(()) }
|
fn open(&mut self, _path: &Path, _flags: OFlag) -> Result<RawFd, Self::Error> {
|
||||||
fn close(&mut self, _fd: RawFd) -> Result<(), Self::Error> { Err(()) }
|
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 is_active(&self) -> bool {
|
||||||
fn seat(&self) -> String { String::from("seat0") }
|
false
|
||||||
|
}
|
||||||
|
fn seat(&self) -> String {
|
||||||
|
String::from("seat0")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Session> Session for Rc<RefCell<S>> {
|
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
|
//! See also `examples/udev.rs` for pure hardware backed example of a compositor utilizing this
|
||||||
//! backend.
|
//! 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::fcntl;
|
||||||
use nix::sys::stat::{dev_t, fstat};
|
use nix::sys::stat::{dev_t, fstat};
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::{Error as IoError, Result as IoResult};
|
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
|
use std::io::{Error as IoError, Result as IoResult};
|
||||||
use std::mem::drop;
|
use std::mem::drop;
|
||||||
use std::path::{PathBuf, Path};
|
|
||||||
use std::os::unix::io::AsRawFd;
|
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 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.
|
/// Graphical backend that monitors available drm devices.
|
||||||
///
|
///
|
||||||
/// Provides a way to automatically initialize a `DrmDevice` for available gpus and notifies the
|
/// 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
|
/// given handler of any changes. Can be used to provide hot-plug functionality for gpus and
|
||||||
/// attached monitors.
|
/// attached monitors.
|
||||||
pub struct UdevBackend<B: Borrow<DrmBackend> + 'static, H: DrmHandler<B> + 'static, S: Session + 'static, T: UdevHandler<B, H> + 'static> {
|
pub struct UdevBackend<
|
||||||
devices: HashMap<dev_t, (StateToken<DrmDevice<B>>, FdEventSource<(StateToken<DrmDevice<B>>, H)>)>,
|
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,
|
monitor: MonitorSocket,
|
||||||
session: S,
|
session: S,
|
||||||
handler: T,
|
handler: T,
|
||||||
logger: ::slog::Logger,
|
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.
|
/// Creates a new `UdevBackend` and adds it to the given `EventLoop`'s state.
|
||||||
///
|
///
|
||||||
/// ## Arguments
|
/// ## 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
|
/// `session` - A session used to open and close devices as they become available
|
||||||
/// `handler` - User-provided handler to respond to any detected changes
|
/// `handler` - User-provided handler to respond to any detected changes
|
||||||
/// `logger` - slog Logger to be used by the backend and its `DrmDevices`.
|
/// `logger` - slog Logger to be used by the backend and its `DrmDevices`.
|
||||||
pub fn new<'a, L>(mut evlh: &mut EventLoopHandle,
|
pub fn new<'a, L>(
|
||||||
context: &Context,
|
mut evlh: &mut EventLoopHandle, context: &Context, mut session: S, mut handler: T, logger: L
|
||||||
mut session: S,
|
) -> Result<StateToken<UdevBackend<B, H, S, T>>>
|
||||||
mut handler: T,
|
|
||||||
logger: L)
|
|
||||||
-> Result<StateToken<UdevBackend<B, H, S, T>>>
|
|
||||||
where
|
where
|
||||||
L: Into<Option<::slog::Logger>>
|
L: Into<Option<::slog::Logger>>,
|
||||||
{
|
{
|
||||||
let logger = ::slog_or_stdlog(logger).new(o!("smithay_module" => "backend_udev"));
|
let logger = ::slog_or_stdlog(logger).new(o!("smithay_module" => "backend_udev"));
|
||||||
let seat = session.seat();
|
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)>)>>();
|
.collect::<HashMap<dev_t, (StateToken<DrmDevice<B>>, FdEventSource<(StateToken<DrmDevice<B>>, H)>)>>();
|
||||||
|
|
||||||
let mut builder = MonitorBuilder::new(context).chain_err(|| ErrorKind::FailedToInitMonitor)?;
|
let mut builder = MonitorBuilder::new(context).chain_err(|| ErrorKind::FailedToInitMonitor)?;
|
||||||
builder.match_subsystem("drm").chain_err(|| ErrorKind::FailedToInitMonitor)?;
|
builder
|
||||||
let monitor = builder.listen().chain_err(|| ErrorKind::FailedToInitMonitor)?;
|
.match_subsystem("drm")
|
||||||
|
.chain_err(|| ErrorKind::FailedToInitMonitor)?;
|
||||||
|
let monitor = builder
|
||||||
|
.listen()
|
||||||
|
.chain_err(|| ErrorKind::FailedToInitMonitor)?;
|
||||||
|
|
||||||
Ok(evlh.state().insert(UdevBackend {
|
Ok(evlh.state().insert(UdevBackend {
|
||||||
devices,
|
devices,
|
||||||
|
@ -154,14 +170,22 @@ impl<B: From<DrmBackend> + Borrow<DrmBackend> + 'static, H: DrmHandler<B> + 'sta
|
||||||
let fd = device.as_raw_fd();
|
let fd = device.as_raw_fd();
|
||||||
drop(device);
|
drop(device);
|
||||||
if let Err(err) = self.session.close(fd) {
|
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");
|
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>) {
|
fn pause<'a>(&mut self, state: &mut StateProxy<'a>) {
|
||||||
state.with_value(self, |state, udev| {
|
state.with_value(self, |state, udev| {
|
||||||
for &mut (ref mut device, _) in udev.devices.values_mut() {
|
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`.
|
/// Allows the backend to recieve kernel events and thus to drive the `UdevHandler`.
|
||||||
/// No runtime functionality can be provided without using this function.
|
/// 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>>)
|
pub fn udev_backend_bind<B, S, H, T>(
|
||||||
-> IoResult<FdEventSource<StateToken<UdevBackend<B, H, S, T>>>>
|
evlh: &mut EventLoopHandle, udev: StateToken<UdevBackend<B, H, S, T>>
|
||||||
|
) -> IoResult<FdEventSource<StateToken<UdevBackend<B, H, S, T>>>>
|
||||||
where
|
where
|
||||||
B: From<DrmBackend> + Borrow<DrmBackend> + 'static,
|
B: From<DrmBackend> + Borrow<DrmBackend> + 'static,
|
||||||
H: DrmHandler<B> + 'static,
|
H: DrmHandler<B> + 'static,
|
||||||
|
@ -192,16 +217,10 @@ where
|
||||||
S: Session + 'static,
|
S: Session + 'static,
|
||||||
{
|
{
|
||||||
let fd = evlh.state().get(&udev).monitor.as_raw_fd();
|
let fd = evlh.state().get(&udev).monitor.as_raw_fd();
|
||||||
evlh.add_fd_event_source(
|
evlh.add_fd_event_source(fd, fd_event_source_implementation(), udev, FdInterest::READ)
|
||||||
fd,
|
|
||||||
fd_event_source_implementation(),
|
|
||||||
udev,
|
|
||||||
FdInterest::READ,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fd_event_source_implementation<B, S, H, T>()
|
fn fd_event_source_implementation<B, S, H, T>() -> FdEventSourceImpl<StateToken<UdevBackend<B, H, S, T>>>
|
||||||
-> FdEventSourceImpl<StateToken<UdevBackend<B, H, S, T>>>
|
|
||||||
where
|
where
|
||||||
B: From<DrmBackend> + Borrow<DrmBackend> + 'static,
|
B: From<DrmBackend> + Borrow<DrmBackend> + 'static,
|
||||||
H: DrmHandler<B> + 'static,
|
H: DrmHandler<B> + 'static,
|
||||||
|
@ -210,7 +229,11 @@ where
|
||||||
{
|
{
|
||||||
FdEventSourceImpl {
|
FdEventSourceImpl {
|
||||||
ready: |mut evlh, token, _, _| {
|
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 {
|
for event in events {
|
||||||
match event.event_type() {
|
match event.event_type() {
|
||||||
// New device
|
// New device
|
||||||
|
@ -218,30 +241,49 @@ where
|
||||||
info!(evlh.state().get(token).logger, "Device Added");
|
info!(evlh.state().get(token).logger, "Device Added");
|
||||||
if let (Some(path), Some(devnum)) = (event.devnode(), event.devnum()) {
|
if let (Some(path), Some(devnum)) = (event.devnode(), event.devnum()) {
|
||||||
let mut device = {
|
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) {
|
let logger = evlh.state().get(token).logger.clone();
|
||||||
Ok(fd) => fd,
|
match evlh.state().get_mut(token).session.open(
|
||||||
Err(err) => {
|
path,
|
||||||
warn!(logger, "Unable to open drm device {:?}, Error: {:?}. Skipping", path, err);
|
fcntl::O_RDWR | fcntl::O_CLOEXEC | fcntl::O_NOCTTY
|
||||||
continue;
|
| 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,
|
Ok(dev) => dev,
|
||||||
Err(err) => {
|
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;
|
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) => {
|
Some(drm_handler) => {
|
||||||
let dev_token = evlh.state().insert(device);
|
let dev_token = evlh.state().insert(device);
|
||||||
if let Ok(fd_event_source) = drm_device_bind(&mut evlh, dev_token.clone(), drm_handler) {
|
if let Ok(fd_event_source) =
|
||||||
evlh.state().get_mut(token).devices.insert(devnum, (dev_token, 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 {
|
} else {
|
||||||
evlh.state().with_value(token, |state, udev| {
|
evlh.state().with_value(token, |state, udev| {
|
||||||
let mut state: StateProxy = state.into();
|
let mut state: StateProxy = state.into();
|
||||||
|
@ -250,42 +292,52 @@ where
|
||||||
let fd = device.as_raw_fd();
|
let fd = device.as_raw_fd();
|
||||||
drop(device);
|
drop(device);
|
||||||
if let Err(err) = udev.session.close(fd) {
|
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 => {
|
None => {
|
||||||
let fd = device.as_raw_fd();
|
let fd = device.as_raw_fd();
|
||||||
drop(device);
|
drop(device);
|
||||||
evlh.state().with_value(token, |_state, udev| {
|
evlh.state().with_value(token, |_state, udev| {
|
||||||
if let Err(err) = udev.session.close(fd) {
|
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
|
// Device removed
|
||||||
EventType::Remove => {
|
EventType::Remove => evlh.state().with_value(token, |state, udev| {
|
||||||
evlh.state().with_value(token, |state, udev| {
|
info!(udev.logger, "Device Remove");
|
||||||
info!(udev.logger, "Device Remove");
|
if let Some(devnum) = event.devnum() {
|
||||||
if let Some(devnum) = event.devnum() {
|
if let Some((device, fd_event_source)) = udev.devices.remove(&devnum) {
|
||||||
if let Some((device, fd_event_source)) = udev.devices.remove(&devnum) {
|
fd_event_source.remove();
|
||||||
fd_event_source.remove();
|
let mut state: StateProxy = state.into();
|
||||||
let mut state: StateProxy = state.into();
|
udev.handler.device_removed(&mut state, &device);
|
||||||
udev.handler.device_removed(&mut state, &device);
|
let device = state.remove(device);
|
||||||
let device = state.remove(device);
|
let fd = device.as_raw_fd();
|
||||||
let fd = device.as_raw_fd();
|
drop(device);
|
||||||
drop(device);
|
if let Err(err) = udev.session.close(fd) {
|
||||||
if let Err(err) = udev.session.close(fd) {
|
warn!(
|
||||||
warn!(udev.logger, "Failed to close device {:?}. Error: {:?}. Ignoring", event.sysname(), err);
|
udev.logger,
|
||||||
};
|
"Failed to close device {:?}. Error: {:?}. Ignoring",
|
||||||
}
|
event.sysname(),
|
||||||
|
err
|
||||||
|
);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
},
|
}),
|
||||||
// New connector
|
// New connector
|
||||||
EventType::Change => evlh.state().with_value(token, |state, udev| {
|
EventType::Change => evlh.state().with_value(token, |state, udev| {
|
||||||
info!(udev.logger, "Device Changed");
|
info!(udev.logger, "Device Changed");
|
||||||
|
@ -301,25 +353,28 @@ where
|
||||||
info!(udev.logger, "changed, but no devnum");
|
info!(udev.logger, "changed, but no devnum");
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
_ => {},
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: |evlh, token, _, err| {
|
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.
|
/// 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.
|
/// 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.
|
/// Returning a `DrmHandler` will initialize the device, returning `None` will ignore the device.
|
||||||
///
|
///
|
||||||
/// ## Panics
|
/// ## Panics
|
||||||
/// Panics if you try to borrow the token of the belonging `UdevBackend` using this `StateProxy`.
|
/// 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.
|
/// Called when an open device is changed.
|
||||||
///
|
///
|
||||||
/// This usually indicates that some connectors did become available or were unplugged. The handler
|
/// 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;
|
let mut result = None;
|
||||||
for device in enumerator.scan_devices()? {
|
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(pci) = device.parent_with_subsystem(Path::new("pci"))? {
|
||||||
if let Some(id) = pci.attribute_value("boot_vga") {
|
if let Some(id) = pci.attribute_value("boot_vga") {
|
||||||
if id == "1" {
|
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)?;
|
let mut enumerator = Enumerator::new(context)?;
|
||||||
enumerator.match_subsystem("drm")?;
|
enumerator.match_subsystem("drm")?;
|
||||||
enumerator.match_sysname("card[0-9]*")?;
|
enumerator.match_sysname("card[0-9]*")?;
|
||||||
Ok(enumerator.scan_devices()?
|
Ok(enumerator
|
||||||
.filter(|device| device.property_value("ID_SEAT").map(|x| x.to_os_string()).unwrap_or(OsString::from("seat0")) == *seat.as_ref())
|
.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))
|
.flat_map(|device| device.devnode().map(PathBuf::from))
|
||||||
.collect()
|
.collect())
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error_chain! {
|
error_chain! {
|
||||||
|
|
|
@ -99,8 +99,9 @@ where
|
||||||
/// Create a new `WinitGraphicsBackend`, which implements the `EGLGraphicsBackend`
|
/// Create a new `WinitGraphicsBackend`, which implements the `EGLGraphicsBackend`
|
||||||
/// graphics backend trait, from a given `WindowBuilder` struct and a corresponding
|
/// graphics backend trait, from a given `WindowBuilder` struct and a corresponding
|
||||||
/// `WinitInputBackend`, which implements the `InputBackend` trait
|
/// `WinitInputBackend`, which implements the `InputBackend` trait
|
||||||
pub fn init_from_builder<L>(builder: WindowBuilder, logger: L)
|
pub fn init_from_builder<L>(
|
||||||
-> Result<(WinitGraphicsBackend, WinitInputBackend)>
|
builder: WindowBuilder, logger: L
|
||||||
|
) -> Result<(WinitGraphicsBackend, WinitInputBackend)>
|
||||||
where
|
where
|
||||||
L: Into<Option<::slog::Logger>>,
|
L: Into<Option<::slog::Logger>>,
|
||||||
{
|
{
|
||||||
|
@ -120,8 +121,9 @@ where
|
||||||
/// graphics backend trait, from a given `WindowBuilder` struct, as well as given
|
/// graphics backend trait, from a given `WindowBuilder` struct, as well as given
|
||||||
/// `GlAttributes` for further customization of the rendering pipeline and a
|
/// `GlAttributes` for further customization of the rendering pipeline and a
|
||||||
/// corresponding `WinitInputBackend`, which implements the `InputBackend` trait.
|
/// corresponding `WinitInputBackend`, which implements the `InputBackend` trait.
|
||||||
pub fn init_from_builder_with_gl_attr<L>(builder: WindowBuilder, attributes: GlAttributes, logger: L)
|
pub fn init_from_builder_with_gl_attr<L>(
|
||||||
-> Result<(WinitGraphicsBackend, WinitInputBackend)>
|
builder: WindowBuilder, attributes: GlAttributes, logger: L
|
||||||
|
) -> Result<(WinitGraphicsBackend, WinitInputBackend)>
|
||||||
where
|
where
|
||||||
L: Into<Option<::slog::Logger>>,
|
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)
|
self.window.head().set_cursor_position(x as i32, y as i32)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_cursor_representation(&self, cursor: &Self::CursorFormat, _hotspot: (u32, u32))
|
fn set_cursor_representation(
|
||||||
-> ::std::result::Result<(), ()> {
|
&self, cursor: &Self::CursorFormat, _hotspot: (u32, u32)
|
||||||
|
) -> ::std::result::Result<(), ()> {
|
||||||
// Cannot log this one, as `CursorFormat` is not `Debug` and should not be
|
// Cannot log this one, as `CursorFormat` is not `Debug` and should not be
|
||||||
debug!(self.logger, "Changing cursor representation");
|
debug!(self.logger, "Changing cursor representation");
|
||||||
self.window.head().set_cursor(*cursor);
|
self.window.head().set_cursor(*cursor);
|
||||||
|
@ -228,7 +231,8 @@ impl EGLGraphicsBackend for WinitGraphicsBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_current(&self) -> bool {
|
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> {
|
unsafe fn make_current(&self) -> ::std::result::Result<(), SwapBuffersError> {
|
||||||
|
@ -371,10 +375,10 @@ impl PointerAxisEvent for WinitMouseWheelEvent {
|
||||||
|
|
||||||
fn amount(&self) -> f64 {
|
fn amount(&self) -> f64 {
|
||||||
match (self.axis, self.delta) {
|
match (self.axis, self.delta) {
|
||||||
(Axis::Horizontal, MouseScrollDelta::LineDelta(x, _)) |
|
(Axis::Horizontal, MouseScrollDelta::LineDelta(x, _))
|
||||||
(Axis::Horizontal, MouseScrollDelta::PixelDelta(x, _)) => x as f64,
|
| (Axis::Horizontal, MouseScrollDelta::PixelDelta(x, _)) => x as f64,
|
||||||
(Axis::Vertical, MouseScrollDelta::LineDelta(_, y)) |
|
(Axis::Vertical, MouseScrollDelta::LineDelta(_, y))
|
||||||
(Axis::Vertical, MouseScrollDelta::PixelDelta(_, y)) => y as f64,
|
| (Axis::Vertical, MouseScrollDelta::PixelDelta(_, y)) => y as f64,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -624,8 +628,10 @@ impl InputBackend for WinitInputBackend {
|
||||||
trace!(logger, "Resizing window to {:?}", (x, y));
|
trace!(logger, "Resizing window to {:?}", (x, y));
|
||||||
window.head().set_inner_size(x, y);
|
window.head().set_inner_size(x, y);
|
||||||
window.rent(|egl| {
|
window.rent(|egl| {
|
||||||
egl.rent(|surface| if let Some(wegl_surface) = (**surface).as_ref() {
|
egl.rent(|surface| {
|
||||||
wegl_surface.resize(x as i32, y as i32, 0, 0)
|
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
|
* wl_compositor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pub(crate) fn compositor_bind<U, R, ID>(evlh: &mut EventLoopHandle, idata: &mut SurfaceIData<U, R, ID>,
|
pub(crate) fn compositor_bind<U, R, ID>(
|
||||||
_: &Client, compositor: wl_compositor::WlCompositor)
|
evlh: &mut EventLoopHandle, idata: &mut SurfaceIData<U, R, ID>, _: &Client,
|
||||||
where
|
compositor: wl_compositor::WlCompositor,
|
||||||
|
) where
|
||||||
U: Default + 'static,
|
U: Default + 'static,
|
||||||
R: Default + 'static,
|
R: Default + 'static,
|
||||||
ID: 'static,
|
ID: 'static,
|
||||||
|
@ -65,8 +66,9 @@ pub struct SurfaceIData<U, R, ID> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<U, R, ID> 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)
|
pub(crate) fn make(
|
||||||
-> SurfaceIData<U, R, ID> {
|
log: ::slog::Logger, implem: SurfaceUserImplementation<U, R, ID>, idata: ID
|
||||||
|
) -> SurfaceIData<U, R, ID> {
|
||||||
SurfaceIData {
|
SurfaceIData {
|
||||||
log: log,
|
log: log,
|
||||||
implem: implem,
|
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>(
|
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 {
|
wl_surface::Implementation {
|
||||||
attach: |_, _, _, surface, buffer, x, y| unsafe {
|
attach: |_, _, _, surface, buffer, x, y| unsafe {
|
||||||
SurfaceData::<U, R>::with_data(surface, |d| {
|
SurfaceData::<U, R>::with_data(surface, |d| {
|
||||||
|
@ -199,9 +199,9 @@ fn destroy_region(region: &wl_region::WlRegion) {
|
||||||
* wl_subcompositor
|
* wl_subcompositor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pub(crate) fn subcompositor_bind<U, R>(evlh: &mut EventLoopHandle, _: &mut (), _: &Client,
|
pub(crate) fn subcompositor_bind<U, R>(
|
||||||
subcompositor: wl_subcompositor::WlSubcompositor)
|
evlh: &mut EventLoopHandle, _: &mut (), _: &Client, subcompositor: wl_subcompositor::WlSubcompositor
|
||||||
where
|
) where
|
||||||
R: RoleType + Role<SubsurfaceRole> + 'static,
|
R: RoleType + Role<SubsurfaceRole> + 'static,
|
||||||
U: 'static,
|
U: 'static,
|
||||||
{
|
{
|
||||||
|
|
|
@ -314,11 +314,11 @@ where
|
||||||
///
|
///
|
||||||
/// If the surface not managed by the CompositorGlobal that provided this token, this
|
/// If the surface not managed by the CompositorGlobal that provided this token, this
|
||||||
/// will panic (having more than one compositor is not supported).
|
/// will panic (having more than one compositor is not supported).
|
||||||
pub fn with_surface_tree_upward<F, T>(&self, surface: &wl_surface::WlSurface, initial: T, f: F)
|
pub fn with_surface_tree_upward<F, T>(
|
||||||
-> Result<(), ()>
|
&self, surface: &wl_surface::WlSurface, initial: T, f: F
|
||||||
|
) -> Result<(), ()>
|
||||||
where
|
where
|
||||||
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T)
|
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> TraversalAction<T>,
|
||||||
-> TraversalAction<T>,
|
|
||||||
{
|
{
|
||||||
assert!(
|
assert!(
|
||||||
resource_is_registered(
|
resource_is_registered(
|
||||||
|
@ -340,11 +340,11 @@ where
|
||||||
/// supposed to be drawn: top-most first.
|
/// supposed to be drawn: top-most first.
|
||||||
///
|
///
|
||||||
/// Behavior is the same as `with_surface_tree_upward`.
|
/// 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)
|
pub fn with_surface_tree_downward<F, T>(
|
||||||
-> Result<(), ()>
|
&self, surface: &wl_surface::WlSurface, initial: T, f: F
|
||||||
|
) -> Result<(), ()>
|
||||||
where
|
where
|
||||||
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T)
|
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> TraversalAction<T>,
|
||||||
-> TraversalAction<T>,
|
|
||||||
{
|
{
|
||||||
assert!(
|
assert!(
|
||||||
resource_is_registered(
|
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) }
|
unsafe { SurfaceData::<U, R>::has_role::<RoleData>(surface) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Register that this surface has given role with default data
|
/// Register that this surface has given role with default data
|
||||||
///
|
///
|
||||||
/// Fails if the surface already has a role.
|
/// 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
|
/// If the surface is not managed by the CompositorGlobal that provided this token, this
|
||||||
/// will panic (having more than one compositor is not supported).
|
/// will panic (having more than one compositor is not supported).
|
||||||
pub fn give_role_with<RoleData>(&self, surface: &wl_surface::WlSurface, data: RoleData)
|
pub fn give_role_with<RoleData>(
|
||||||
-> Result<(), RoleData>
|
&self, surface: &wl_surface::WlSurface, data: RoleData
|
||||||
|
) -> Result<(), RoleData>
|
||||||
where
|
where
|
||||||
R: Role<RoleData>,
|
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
|
/// If the surface is not managed by the CompositorGlobal that provided this token, this
|
||||||
/// will panic (having more than one compositor is not supported).
|
/// will panic (having more than one compositor is not supported).
|
||||||
pub fn with_role_data<RoleData, F, T>(&self, surface: &wl_surface::WlSurface, f: F)
|
pub fn with_role_data<RoleData, F, T>(
|
||||||
-> Result<T, WrongRole>
|
&self, surface: &wl_surface::WlSurface, f: F
|
||||||
|
) -> Result<T, WrongRole>
|
||||||
where
|
where
|
||||||
R: Role<RoleData>,
|
R: Role<RoleData>,
|
||||||
F: FnOnce(&mut RoleData) -> T,
|
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
|
/// It also returns the two global handles, in case you whish to remove these
|
||||||
/// globals from the event loop in the future.
|
/// globals from the event loop in the future.
|
||||||
pub fn compositor_init<U, R, ID, L>(
|
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>,
|
CompositorToken<U, R, ID>,
|
||||||
Global<wl_compositor::WlCompositor, self::handlers::SurfaceIData<U, R, ID>>,
|
Global<wl_compositor::WlCompositor, self::handlers::SurfaceIData<U, R, ID>>,
|
||||||
Global<wl_subcompositor::WlSubcompositor, ()>,
|
Global<wl_subcompositor::WlSubcompositor, ()>,
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
L: Into<Option<::slog::Logger>>,
|
L: Into<Option<::slog::Logger>>,
|
||||||
U: Default + 'static,
|
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)
|
/// See [`wayland_server::protocol::wl_surface::Implementation::commit`](https://docs.rs/wayland-server/0.10.1/wayland_server/protocol/wl_surface/struct.Implementation.html#structfield.commit)
|
||||||
/// for more details
|
/// for more details
|
||||||
pub commit: fn(
|
pub commit: fn(
|
||||||
evlh: &mut EventLoopHandle,
|
evlh: &mut EventLoopHandle,
|
||||||
idata: &mut ID,
|
idata: &mut ID,
|
||||||
surface: &wl_surface::WlSurface,
|
surface: &wl_surface::WlSurface,
|
||||||
token: CompositorToken<U, R, ID>,
|
token: CompositorToken<U, R, ID>,
|
||||||
),
|
),
|
||||||
/// The client asks to be notified when would be a good time to update the contents of this surface
|
/// The client asks to be notified when would be a good time to update the contents of this surface
|
||||||
///
|
///
|
||||||
|
@ -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)
|
/// See [`wayland_server::protocol::wl_surface::Implementation::frame`](https://docs.rs/wayland-server/0.10.1/wayland_server/protocol/wl_surface/struct.Implementation.html#structfield.frame)
|
||||||
/// for more details
|
/// for more details
|
||||||
pub frame: fn(
|
pub frame: fn(
|
||||||
evlh: &mut EventLoopHandle,
|
evlh: &mut EventLoopHandle,
|
||||||
idata: &mut ID,
|
idata: &mut ID,
|
||||||
surface: &wl_surface::WlSurface,
|
surface: &wl_surface::WlSurface,
|
||||||
callback: wl_callback::WlCallback,
|
callback: wl_callback::WlCallback,
|
||||||
token: CompositorToken<U, R, ID>,
|
token: CompositorToken<U, R, ID>,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,8 +132,9 @@ impl<U: 'static, R: RoleType + 'static> SurfaceData<U, R> {
|
||||||
/// Register that this surface has a role with given data
|
/// Register that this surface has a role with given data
|
||||||
///
|
///
|
||||||
/// Fails if it already has one and returns the data
|
/// Fails if it already has one and returns the data
|
||||||
pub unsafe fn give_role_with<RoleData>(surface: &wl_surface::WlSurface, data: RoleData)
|
pub unsafe fn give_role_with<RoleData>(
|
||||||
-> Result<(), RoleData>
|
surface: &wl_surface::WlSurface, data: RoleData
|
||||||
|
) -> Result<(), RoleData>
|
||||||
where
|
where
|
||||||
R: Role<RoleData>,
|
R: Role<RoleData>,
|
||||||
{
|
{
|
||||||
|
@ -158,8 +159,9 @@ impl<U: 'static, R: RoleType + 'static> SurfaceData<U, R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Access to the role data
|
/// Access to the role data
|
||||||
pub unsafe fn with_role_data<RoleData, F, T>(surface: &wl_surface::WlSurface, f: F)
|
pub unsafe fn with_role_data<RoleData, F, T>(
|
||||||
-> Result<T, WrongRole>
|
surface: &wl_surface::WlSurface, f: F
|
||||||
|
) -> Result<T, WrongRole>
|
||||||
where
|
where
|
||||||
R: Role<RoleData>,
|
R: Role<RoleData>,
|
||||||
F: FnOnce(&mut RoleData) -> T,
|
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
|
/// if this surface already has a role, does nothing and fails, otherwise
|
||||||
/// its role is now to be a subsurface
|
/// its role is now to be a subsurface
|
||||||
pub unsafe fn set_parent(child: &wl_surface::WlSurface, parent: &wl_surface::WlSurface)
|
pub unsafe fn set_parent(
|
||||||
-> Result<(), ()> {
|
child: &wl_surface::WlSurface, parent: &wl_surface::WlSurface
|
||||||
|
) -> Result<(), ()> {
|
||||||
debug_assert!(child.status() == Liveness::Alive);
|
debug_assert!(child.status() == Liveness::Alive);
|
||||||
debug_assert!(parent.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
|
/// Reorders a surface relative to one of its sibling
|
||||||
///
|
///
|
||||||
/// Fails if `relative_to` is not a sibling or parent of `surface`.
|
/// Fails if `relative_to` is not a sibling or parent of `surface`.
|
||||||
pub unsafe fn reorder(surface: &wl_surface::WlSurface, to: Location,
|
pub unsafe fn reorder(
|
||||||
relative_to: &wl_surface::WlSurface)
|
surface: &wl_surface::WlSurface, to: Location, relative_to: &wl_surface::WlSurface
|
||||||
-> Result<(), ()> {
|
) -> Result<(), ()> {
|
||||||
let parent = {
|
let parent = {
|
||||||
let data_mutex = Self::get_data(surface);
|
let data_mutex = Self::get_data(surface);
|
||||||
let data_guard = data_mutex.lock().unwrap();
|
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.
|
/// false will cause an early-stopping.
|
||||||
pub unsafe fn map_tree<F, T>(root: &wl_surface::WlSurface, initial: T, mut f: F, reverse: bool)
|
pub unsafe fn map_tree<F, T>(root: &wl_surface::WlSurface, initial: T, mut f: F, reverse: bool)
|
||||||
where
|
where
|
||||||
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T)
|
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> TraversalAction<T>,
|
||||||
-> TraversalAction<T>,
|
|
||||||
{
|
{
|
||||||
// helper function for recursion
|
// helper function for recursion
|
||||||
unsafe fn map<U: 'static, R: 'static, F, T>(surface: &wl_surface::WlSurface,
|
unsafe fn map<U: 'static, R: 'static, F, T>(
|
||||||
root: &wl_surface::WlSurface, initial: &T, f: &mut F,
|
surface: &wl_surface::WlSurface, root: &wl_surface::WlSurface, initial: &T, f: &mut F,
|
||||||
reverse: bool)
|
reverse: bool,
|
||||||
-> bool
|
) -> bool
|
||||||
where
|
where
|
||||||
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T)
|
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> TraversalAction<T>,
|
||||||
-> TraversalAction<T>,
|
|
||||||
{
|
{
|
||||||
// stop if we met the root, so to not deadlock/inifinte loop
|
// stop if we met the root, so to not deadlock/inifinte loop
|
||||||
if surface.equals(root) {
|
if surface.equals(root) {
|
||||||
|
|
|
@ -113,11 +113,11 @@ impl Output {
|
||||||
/// returns the state token allowing you to access it, as well as the global handle,
|
/// 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.
|
/// in case you whish to remove this global in the future.
|
||||||
pub fn new<L>(
|
pub fn new<L>(
|
||||||
evl: &mut EventLoop, name: String, physical: PhysicalProperties, logger: L)
|
evl: &mut EventLoop, name: String, physical: PhysicalProperties, logger: L
|
||||||
-> (
|
) -> (
|
||||||
StateToken<Output>,
|
StateToken<Output>,
|
||||||
Global<wl_output::WlOutput, StateToken<Output>>,
|
Global<wl_output::WlOutput, StateToken<Output>>,
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
L: Into<Option<::slog::Logger>>,
|
L: Into<Option<::slog::Logger>>,
|
||||||
{
|
{
|
||||||
|
@ -229,8 +229,10 @@ impl Output {
|
||||||
/// internal list.
|
/// internal list.
|
||||||
///
|
///
|
||||||
/// By default, transform status is `Normal`, and scale is `1`.
|
/// By default, transform status is `Normal`, and scale is `1`.
|
||||||
pub fn change_current_state(&mut self, new_mode: Option<Mode>,
|
pub fn change_current_state(
|
||||||
new_transform: Option<wl_output::Transform>, new_scale: Option<i32>) {
|
&mut self, new_mode: Option<Mode>, new_transform: Option<wl_output::Transform>,
|
||||||
|
new_scale: Option<i32>,
|
||||||
|
) {
|
||||||
if let Some(mode) = new_mode {
|
if let Some(mode) = new_mode {
|
||||||
if self.modes.iter().find(|&m| *m == mode).is_none() {
|
if self.modes.iter().find(|&m| *m == mode).is_none() {
|
||||||
self.modes.push(mode);
|
self.modes.push(mode);
|
||||||
|
@ -283,8 +285,9 @@ impl Output {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn output_bind(evlh: &mut EventLoopHandle, token: &mut StateToken<Output>, _: &Client,
|
fn output_bind(
|
||||||
global: wl_output::WlOutput) {
|
evlh: &mut EventLoopHandle, token: &mut StateToken<Output>, _: &Client, global: wl_output::WlOutput
|
||||||
|
) {
|
||||||
evlh.register(&global, output_implementation(), token.clone(), None);
|
evlh.register(&global, output_implementation(), token.clone(), None);
|
||||||
evlh.state().get_mut(token).new_global(global);
|
evlh.state().get_mut(token).new_global(global);
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,9 +66,10 @@ struct KbdInternal {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KbdInternal {
|
impl KbdInternal {
|
||||||
fn new(rules: &str, model: &str, layout: &str, variant: &str, options: Option<String>,
|
fn new(
|
||||||
repeat_rate: i32, repeat_delay: i32)
|
rules: &str, model: &str, layout: &str, variant: &str, options: Option<String>, repeat_rate: i32,
|
||||||
-> Result<KbdInternal, ()> {
|
repeat_delay: i32,
|
||||||
|
) -> Result<KbdInternal, ()> {
|
||||||
// we create a new contex for each keyboard because libxkbcommon is actually NOT threadsafe
|
// 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
|
// so confining it inside the KbdInternal allows us to use Rusts mutability rules to make
|
||||||
// sure nothing goes wrong.
|
// sure nothing goes wrong.
|
||||||
|
@ -168,10 +169,10 @@ pub enum Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a keyboard handler from a set of RMLVO rules
|
/// Create a keyboard handler from a set of RMLVO rules
|
||||||
pub(crate) fn create_keyboard_handler(rules: &str, model: &str, layout: &str, variant: &str,
|
pub(crate) fn create_keyboard_handler(
|
||||||
options: Option<String>, repeat_delay: i32, repeat_rate: i32,
|
rules: &str, model: &str, layout: &str, variant: &str, options: Option<String>, repeat_delay: i32,
|
||||||
logger: &::slog::Logger)
|
repeat_rate: i32, logger: &::slog::Logger,
|
||||||
-> Result<KeyboardHandle, Error> {
|
) -> Result<KeyboardHandle, Error> {
|
||||||
let log = logger.new(o!("smithay_module" => "xkbcommon_handler"));
|
let log = logger.new(o!("smithay_module" => "xkbcommon_handler"));
|
||||||
info!(log, "Initializing a xkbcommon handler with keymap query";
|
info!(log, "Initializing a xkbcommon handler with keymap query";
|
||||||
"rules" => rules, "model" => model, "layout" => layout, "variant" => variant,
|
"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());
|
info!(log, "Loaded Keymap"; "name" => internal.keymap.layouts().next());
|
||||||
|
|
||||||
|
|
||||||
// prepare a tempfile with the keymap, to send it to clients
|
// prepare a tempfile with the keymap, to send it to clients
|
||||||
let mut keymap_file = tempfile().map_err(Error::IoError)?;
|
let mut keymap_file = tempfile().map_err(Error::IoError)?;
|
||||||
let keymap_data = internal.keymap.get_as_string(xkb::KEYMAP_FORMAT_TEXT_V1);
|
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 are provided with the state token to retrieve it (allowing
|
||||||
/// you to add or remove capabilities from it), and the global handle,
|
/// you to add or remove capabilities from it), and the global handle,
|
||||||
/// in case you want to remove it.
|
/// in case you want to remove it.
|
||||||
pub fn new<L>(evl: &mut EventLoop, name: String, logger: L)
|
pub fn new<L>(
|
||||||
-> (StateToken<Seat>, Global<wl_seat::WlSeat, StateToken<Seat>>)
|
evl: &mut EventLoop, name: String, logger: L
|
||||||
|
) -> (StateToken<Seat>, Global<wl_seat::WlSeat, StateToken<Seat>>)
|
||||||
where
|
where
|
||||||
L: Into<Option<::slog::Logger>>,
|
L: Into<Option<::slog::Logger>>,
|
||||||
{
|
{
|
||||||
|
@ -158,9 +159,10 @@ impl Seat {
|
||||||
/// Calling this method on a seat that already has a keyboard capability
|
/// 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
|
/// will overwrite it, and will be seen by the clients as if the
|
||||||
/// keyboard was unplugged and a new one was plugged.
|
/// keyboard was unplugged and a new one was plugged.
|
||||||
pub fn add_keyboard(&mut self, model: &str, layout: &str, variant: &str, options: Option<String>,
|
pub fn add_keyboard(
|
||||||
repeat_delay: i32, repeat_rate: i32)
|
&mut self, model: &str, layout: &str, variant: &str, options: Option<String>, repeat_delay: i32,
|
||||||
-> Result<KeyboardHandle, KeyboardError> {
|
repeat_rate: i32,
|
||||||
|
) -> Result<KeyboardHandle, KeyboardError> {
|
||||||
let keyboard = self::keyboard::create_keyboard_handler(
|
let keyboard = self::keyboard::create_keyboard_handler(
|
||||||
"evdev", // we need this one
|
"evdev", // we need this one
|
||||||
model,
|
model,
|
||||||
|
@ -229,8 +231,9 @@ impl Seat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn seat_global_bind(evlh: &mut EventLoopHandle, token: &mut StateToken<Seat>, _: &Client,
|
fn seat_global_bind(
|
||||||
seat: wl_seat::WlSeat) {
|
evlh: &mut EventLoopHandle, token: &mut StateToken<Seat>, _: &Client, seat: wl_seat::WlSeat
|
||||||
|
) {
|
||||||
evlh.register(&seat, seat_implementation(), token.clone(), None);
|
evlh.register(&seat, seat_implementation(), token.clone(), None);
|
||||||
let seat_mgr = evlh.state().get_mut(token);
|
let seat_mgr = evlh.state().get_mut(token);
|
||||||
seat.name(seat_mgr.name.clone());
|
seat.name(seat_mgr.name.clone());
|
||||||
|
|
|
@ -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.
|
/// globals from the event loop in the future.
|
||||||
pub fn shell_init<U, R, CID, SID, SD, L>(
|
pub fn shell_init<U, R, CID, SID, SD, L>(
|
||||||
evl: &mut EventLoop, token: CompositorToken<U, R, CID>,
|
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>>,
|
StateToken<ShellState<U, R, CID, SD>>,
|
||||||
Global<wl_shell::WlShell, ShellSurfaceIData<U, R, CID, SID, SD>>,
|
Global<wl_shell::WlShell, ShellSurfaceIData<U, R, CID, SID, SD>>,
|
||||||
Global<zxdg_shell_v6::ZxdgShellV6, ShellSurfaceIData<U, R, CID, SID, SD>>,
|
Global<zxdg_shell_v6::ZxdgShellV6, ShellSurfaceIData<U, R, CID, SID, SD>>,
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
U: 'static,
|
U: 'static,
|
||||||
R: Role<ShellSurfaceRole> + 'static,
|
R: Role<ShellSurfaceRole> + 'static,
|
||||||
|
@ -449,7 +449,8 @@ impl<SD> ShellClient<SD> {
|
||||||
}
|
}
|
||||||
match self.kind {
|
match self.kind {
|
||||||
ShellClientKind::Wl(ref shell) => {
|
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();
|
let mut guard = mutex.lock().unwrap();
|
||||||
if guard.0.pending_ping == 0 {
|
if guard.0.pending_ping == 0 {
|
||||||
return Err(());
|
return Err(());
|
||||||
|
@ -486,7 +487,8 @@ impl<SD> ShellClient<SD> {
|
||||||
}
|
}
|
||||||
match self.kind {
|
match self.kind {
|
||||||
ShellClientKind::Wl(ref shell) => {
|
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();
|
let mut guard = mutex.lock().unwrap();
|
||||||
Ok(f(&mut guard.0.data))
|
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
|
/// You need to return a `ToplevelConfigure` from this function, which will be sent
|
||||||
/// to the client to configure this surface
|
/// to the client to configure this surface
|
||||||
pub new_toplevel: fn(
|
pub new_toplevel:
|
||||||
evlh: &mut EventLoopHandle,
|
fn(evlh: &mut EventLoopHandle, idata: &mut SID, surface: ToplevelSurface<U, R, CID, SD>)
|
||||||
idata: &mut SID,
|
-> ToplevelConfigure,
|
||||||
surface: ToplevelSurface<U, R, CID, SD>,
|
|
||||||
) -> ToplevelConfigure,
|
|
||||||
/// A new popup surface was created
|
/// A new popup surface was created
|
||||||
///
|
///
|
||||||
/// You need to return a `PopupConfigure` from this function, which will be sent
|
/// You need to return a `PopupConfigure` from this function, which will be sent
|
||||||
/// to the client to configure this surface
|
/// to the client to configure this surface
|
||||||
pub new_popup: fn(evlh: &mut EventLoopHandle, idata: &mut SID, surface: PopupSurface<U, R, CID, SD>)
|
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
|
/// The client requested the start of an interactive move for this surface
|
||||||
pub move_: fn(
|
pub move_: fn(
|
||||||
evlh: &mut EventLoopHandle,
|
evlh: &mut EventLoopHandle,
|
||||||
idata: &mut SID,
|
idata: &mut SID,
|
||||||
surface: ToplevelSurface<U, R, CID, SD>,
|
surface: ToplevelSurface<U, R, CID, SD>,
|
||||||
seat: &wl_seat::WlSeat,
|
seat: &wl_seat::WlSeat,
|
||||||
serial: u32,
|
serial: u32,
|
||||||
),
|
),
|
||||||
/// The client requested the start of an interactive resize for this surface
|
/// 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.
|
/// The `edges` argument specifies which part of the window's border is being dragged.
|
||||||
pub resize: fn(
|
pub resize: fn(
|
||||||
evlh: &mut EventLoopHandle,
|
evlh: &mut EventLoopHandle,
|
||||||
idata: &mut SID,
|
idata: &mut SID,
|
||||||
surface: ToplevelSurface<U, R, CID, SD>,
|
surface: ToplevelSurface<U, R, CID, SD>,
|
||||||
seat: &wl_seat::WlSeat,
|
seat: &wl_seat::WlSeat,
|
||||||
serial: u32,
|
serial: u32,
|
||||||
edges: zxdg_toplevel_v6::ResizeEdge,
|
edges: zxdg_toplevel_v6::ResizeEdge,
|
||||||
),
|
),
|
||||||
/// This popup requests a grab of the pointer
|
/// This popup requests a grab of the pointer
|
||||||
///
|
///
|
||||||
/// This means it requests to be sent a `popup_done` event when the pointer leaves
|
/// This means it requests to be sent a `popup_done` event when the pointer leaves
|
||||||
/// the grab area.
|
/// the grab area.
|
||||||
pub grab: fn(
|
pub grab: fn(
|
||||||
evlh: &mut EventLoopHandle,
|
evlh: &mut EventLoopHandle,
|
||||||
idata: &mut SID,
|
idata: &mut SID,
|
||||||
surface: PopupSurface<U, R, CID, SD>,
|
surface: PopupSurface<U, R, CID, SD>,
|
||||||
seat: &wl_seat::WlSeat,
|
seat: &wl_seat::WlSeat,
|
||||||
serial: u32,
|
serial: u32,
|
||||||
),
|
),
|
||||||
/// A toplevel surface requested its display state to be changed
|
/// 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
|
/// You are to answer with a `ToplevelConfigure` that will be sent to the client in
|
||||||
/// response.
|
/// response.
|
||||||
pub change_display_state: fn(
|
pub change_display_state: fn(
|
||||||
evlh: &mut EventLoopHandle,
|
evlh: &mut EventLoopHandle,
|
||||||
idata: &mut SID,
|
idata: &mut SID,
|
||||||
surface: ToplevelSurface<U, R, CID, SD>,
|
surface: ToplevelSurface<U, R, CID, SD>,
|
||||||
maximized: Option<bool>,
|
maximized: Option<bool>,
|
||||||
minimized: Option<bool>,
|
minimized: Option<bool>,
|
||||||
fullscreen: Option<bool>,
|
fullscreen: Option<bool>,
|
||||||
output: Option<&wl_output::WlOutput>,
|
output: Option<&wl_output::WlOutput>,
|
||||||
) -> ToplevelConfigure,
|
) -> ToplevelConfigure,
|
||||||
/// The client requests the window menu to be displayed on this surface at this location
|
/// 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
|
/// This menu belongs to the compositor. It is typically expected to contain options for
|
||||||
/// control of the window (maximize/minimize/close/move/etc...).
|
/// control of the window (maximize/minimize/close/move/etc...).
|
||||||
pub show_window_menu: fn(
|
pub show_window_menu: fn(
|
||||||
evlh: &mut EventLoopHandle,
|
evlh: &mut EventLoopHandle,
|
||||||
idata: &mut SID,
|
idata: &mut SID,
|
||||||
surface: ToplevelSurface<U, R, CID, SD>,
|
surface: ToplevelSurface<U, R, CID, SD>,
|
||||||
seat: &wl_seat::WlSeat,
|
seat: &wl_seat::WlSeat,
|
||||||
serial: u32,
|
serial: u32,
|
||||||
x: i32,
|
x: i32,
|
||||||
y: i32,
|
y: i32,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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::{Client, EventLoopHandle, Resource};
|
||||||
use wayland_server::protocol::{wl_output, wl_shell, wl_shell_surface, wl_surface};
|
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,
|
pub(crate) fn wl_shell_bind<U, R, CID, SID, SD>(
|
||||||
idata: &mut ShellSurfaceIData<U, R, CID, SID, SD>,
|
evlh: &mut EventLoopHandle, idata: &mut ShellSurfaceIData<U, R, CID, SID, SD>, _: &Client,
|
||||||
_: &Client, shell: wl_shell::WlShell)
|
shell: wl_shell::WlShell,
|
||||||
where
|
) where
|
||||||
U: 'static,
|
U: 'static,
|
||||||
R: Role<ShellSurfaceRole> + 'static,
|
R: Role<ShellSurfaceRole> + 'static,
|
||||||
CID: '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>(
|
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
|
where
|
||||||
U: 'static,
|
U: 'static,
|
||||||
R: Role<ShellSurfaceRole> + 'static,
|
R: Role<ShellSurfaceRole> + 'static,
|
||||||
|
@ -122,9 +121,9 @@ fn destroy_shell_surface(shell_surface: &wl_shell_surface::WlShellSurface) {
|
||||||
::std::mem::drop(surface);
|
::std::mem::drop(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_toplevel_handle<U, R, H, SD>(token: CompositorToken<U, R, H>,
|
fn make_toplevel_handle<U, R, H, SD>(
|
||||||
resource: &wl_shell_surface::WlShellSurface)
|
token: CompositorToken<U, R, H>, resource: &wl_shell_surface::WlShellSurface
|
||||||
-> super::ToplevelSurface<U, R, H, SD> {
|
) -> super::ToplevelSurface<U, R, H, SD> {
|
||||||
let ptr = resource.get_user_data();
|
let ptr = resource.get_user_data();
|
||||||
let &(ref wl_surface, _) = unsafe { &*(ptr as *mut ShellSurfaceUserData) };
|
let &(ref wl_surface, _) = unsafe { &*(ptr as *mut ShellSurfaceUserData) };
|
||||||
super::ToplevelSurface {
|
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>,
|
fn make_popup_handle<U, R, H, SD>(
|
||||||
resource: &wl_shell_surface::WlShellSurface)
|
token: CompositorToken<U, R, H>, resource: &wl_shell_surface::WlShellSurface
|
||||||
-> super::PopupSurface<U, R, H, SD> {
|
) -> super::PopupSurface<U, R, H, SD> {
|
||||||
let ptr = resource.get_user_data();
|
let ptr = resource.get_user_data();
|
||||||
let &(ref wl_surface, _) = unsafe { &*(ptr as *mut ShellSurfaceUserData) };
|
let &(ref wl_surface, _) = unsafe { &*(ptr as *mut ShellSurfaceUserData) };
|
||||||
super::PopupSurface {
|
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);
|
resource.configure(wl_shell_surface::Resize::empty(), w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wl_handle_display_state_change<U, R, CID, SID, SD>(evlh: &mut EventLoopHandle,
|
fn wl_handle_display_state_change<U, R, CID, SID, SD>(
|
||||||
idata: &ShellSurfaceIData<U, R, CID, SID, SD>,
|
evlh: &mut EventLoopHandle, idata: &ShellSurfaceIData<U, R, CID, SID, SD>,
|
||||||
shell_surface: &wl_shell_surface::WlShellSurface,
|
shell_surface: &wl_shell_surface::WlShellSurface, maximized: Option<bool>, minimized: Option<bool>,
|
||||||
maximized: Option<bool>, minimized: Option<bool>,
|
fullscreen: Option<bool>, output: Option<&wl_output::WlOutput>,
|
||||||
fullscreen: Option<bool>,
|
) {
|
||||||
output: Option<&wl_output::WlOutput>) {
|
|
||||||
let handle = make_toplevel_handle(idata.compositor_token, shell_surface);
|
let handle = make_toplevel_handle(idata.compositor_token, shell_surface);
|
||||||
// handler callback
|
// handler callback
|
||||||
let mut user_idata = idata.idata.borrow_mut();
|
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);
|
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>,
|
fn wl_set_parent<U, R, CID, SID, SD>(
|
||||||
shell_surface: &wl_shell_surface::WlShellSurface,
|
idata: &ShellSurfaceIData<U, R, CID, SID, SD>, shell_surface: &wl_shell_surface::WlShellSurface,
|
||||||
parent: Option<wl_surface::WlSurface>)
|
parent: Option<wl_surface::WlSurface>,
|
||||||
where
|
) where
|
||||||
U: 'static,
|
U: 'static,
|
||||||
R: Role<ShellSurfaceRole> + 'static,
|
R: Role<ShellSurfaceRole> + 'static,
|
||||||
CID: 'static,
|
CID: 'static,
|
||||||
|
@ -204,10 +202,10 @@ where
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wl_ensure_toplevel<U, R, CID, SID, SD>(evlh: &mut EventLoopHandle,
|
fn wl_ensure_toplevel<U, R, CID, SID, SD>(
|
||||||
idata: &ShellSurfaceIData<U, R, CID, SID, SD>,
|
evlh: &mut EventLoopHandle, idata: &ShellSurfaceIData<U, R, CID, SID, SD>,
|
||||||
shell_surface: &wl_shell_surface::WlShellSurface)
|
shell_surface: &wl_shell_surface::WlShellSurface,
|
||||||
where
|
) where
|
||||||
U: 'static,
|
U: 'static,
|
||||||
R: Role<ShellSurfaceRole> + 'static,
|
R: Role<ShellSurfaceRole> + 'static,
|
||||||
CID: 'static,
|
CID: 'static,
|
||||||
|
@ -263,8 +261,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shell_surface_implementation<U, R, CID, SID, SD>(
|
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
|
where
|
||||||
U: 'static,
|
U: 'static,
|
||||||
R: Role<ShellSurfaceRole> + 'static,
|
R: Role<ShellSurfaceRole> + 'static,
|
||||||
|
@ -274,7 +271,8 @@ where
|
||||||
{
|
{
|
||||||
wl_shell_surface::Implementation {
|
wl_shell_surface::Implementation {
|
||||||
pong: |evlh, idata, _, shell_surface, serial| {
|
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 valid = {
|
||||||
let mutex = unsafe { &*(shell.get_user_data() as *mut ShellUserData<SD>) };
|
let mutex = unsafe { &*(shell.get_user_data() as *mut ShellUserData<SD>) };
|
||||||
let mut guard = mutex.lock().unwrap();
|
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::{Client, EventLoopHandle, Resource};
|
||||||
use wayland_server::protocol::{wl_output, wl_surface};
|
use wayland_server::protocol::{wl_output, wl_surface};
|
||||||
|
|
||||||
pub(crate) fn xdg_shell_bind<U, R, CID, SID, SD>(evlh: &mut EventLoopHandle,
|
pub(crate) fn xdg_shell_bind<U, R, CID, SID, SD>(
|
||||||
idata: &mut ShellSurfaceIData<U, R, CID, SID, SD>,
|
evlh: &mut EventLoopHandle, idata: &mut ShellSurfaceIData<U, R, CID, SID, SD>, _: &Client,
|
||||||
_: &Client, shell: zxdg_shell_v6::ZxdgShellV6)
|
shell: zxdg_shell_v6::ZxdgShellV6,
|
||||||
where
|
) where
|
||||||
U: 'static,
|
U: 'static,
|
||||||
R: Role<ShellSurfaceRole> + 'static,
|
R: Role<ShellSurfaceRole> + 'static,
|
||||||
CID: '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>(
|
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
|
where
|
||||||
U: 'static,
|
U: 'static,
|
||||||
R: Role<ShellSurfaceRole> + 'static,
|
R: Role<ShellSurfaceRole> + 'static,
|
||||||
|
@ -104,11 +103,10 @@ where
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
xdg_surface.set_user_data(
|
xdg_surface.set_user_data(Box::into_raw(Box::new((
|
||||||
Box::into_raw(Box::new((unsafe { wl_surface.clone_unchecked() }, unsafe {
|
unsafe { wl_surface.clone_unchecked() },
|
||||||
shell.clone_unchecked()
|
unsafe { shell.clone_unchecked() },
|
||||||
}))) as *mut _,
|
))) as *mut _);
|
||||||
);
|
|
||||||
evlh.register(
|
evlh.register(
|
||||||
&xdg_surface,
|
&xdg_surface,
|
||||||
surface_implementation(),
|
surface_implementation(),
|
||||||
|
@ -151,30 +149,34 @@ fn destroy_positioner(positioner: &zxdg_positioner_v6::ZxdgPositionerV6) {
|
||||||
fn positioner_implementation() -> zxdg_positioner_v6::Implementation<()> {
|
fn positioner_implementation() -> zxdg_positioner_v6::Implementation<()> {
|
||||||
zxdg_positioner_v6::Implementation {
|
zxdg_positioner_v6::Implementation {
|
||||||
destroy: |_, _, _, _| {},
|
destroy: |_, _, _, _| {},
|
||||||
set_size: |_, _, _, positioner, width, height| if width < 1 || height < 1 {
|
set_size: |_, _, _, positioner, width, height| {
|
||||||
positioner.post_error(
|
if width < 1 || height < 1 {
|
||||||
zxdg_positioner_v6::Error::InvalidInput as u32,
|
positioner.post_error(
|
||||||
"Invalid size for positioner.".into(),
|
zxdg_positioner_v6::Error::InvalidInput as u32,
|
||||||
);
|
"Invalid size for positioner.".into(),
|
||||||
} else {
|
);
|
||||||
let ptr = positioner.get_user_data();
|
} else {
|
||||||
let state = unsafe { &mut *(ptr as *mut PositionerState) };
|
let ptr = positioner.get_user_data();
|
||||||
state.rect_size = (width, height);
|
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| {
|
||||||
positioner.post_error(
|
if width < 1 || height < 1 {
|
||||||
zxdg_positioner_v6::Error::InvalidInput as u32,
|
positioner.post_error(
|
||||||
"Invalid size for positioner's anchor rectangle.".into(),
|
zxdg_positioner_v6::Error::InvalidInput as u32,
|
||||||
);
|
"Invalid size for positioner's anchor rectangle.".into(),
|
||||||
} else {
|
);
|
||||||
let ptr = positioner.get_user_data();
|
} else {
|
||||||
let state = unsafe { &mut *(ptr as *mut PositionerState) };
|
let ptr = positioner.get_user_data();
|
||||||
state.anchor_rect = Rectangle {
|
let state = unsafe { &mut *(ptr as *mut PositionerState) };
|
||||||
x,
|
state.anchor_rect = Rectangle {
|
||||||
y,
|
x,
|
||||||
width,
|
y,
|
||||||
height,
|
width,
|
||||||
};
|
height,
|
||||||
|
};
|
||||||
|
}
|
||||||
},
|
},
|
||||||
set_anchor: |_, _, _, positioner, anchor| {
|
set_anchor: |_, _, _, positioner, anchor| {
|
||||||
use self::zxdg_positioner_v6::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();
|
let ptr = surface.get_user_data();
|
||||||
surface.set_user_data(::std::ptr::null_mut());
|
surface.set_user_data(::std::ptr::null_mut());
|
||||||
// drop the state
|
// drop the state
|
||||||
let data =
|
let data = unsafe {
|
||||||
unsafe { Box::from_raw(ptr as *mut (zxdg_surface_v6::ZxdgSurfaceV6, zxdg_shell_v6::ZxdgShellV6)) };
|
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
|
// explicit call to drop to not forget what we're doing here
|
||||||
::std::mem::drop(data);
|
::std::mem::drop(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn surface_implementation<U, R, CID, SID, SD>(
|
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
|
where
|
||||||
U: 'static,
|
U: 'static,
|
||||||
R: Role<ShellSurfaceRole> + '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
|
// 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>,
|
fn with_surface_toplevel_data<U, R, CID, SID, SD, F>(
|
||||||
toplevel: &zxdg_toplevel_v6::ZxdgToplevelV6, f: F)
|
idata: &ShellSurfaceIData<U, R, CID, SID, SD>, toplevel: &zxdg_toplevel_v6::ZxdgToplevelV6, f: F
|
||||||
where
|
) where
|
||||||
U: 'static,
|
U: 'static,
|
||||||
R: Role<ShellSurfaceRole> + 'static,
|
R: Role<ShellSurfaceRole> + 'static,
|
||||||
CID: 'static,
|
CID: 'static,
|
||||||
|
@ -438,13 +440,11 @@ where
|
||||||
.expect("xdg_toplevel exists but surface has not shell_surface role?!");
|
.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,
|
fn xdg_handle_display_state_change<U, R, CID, SID, SD>(
|
||||||
idata: &ShellSurfaceIData<U, R, CID, SID, SD>,
|
evlh: &mut EventLoopHandle, idata: &ShellSurfaceIData<U, R, CID, SID, SD>,
|
||||||
toplevel: &zxdg_toplevel_v6::ZxdgToplevelV6,
|
toplevel: &zxdg_toplevel_v6::ZxdgToplevelV6, maximized: Option<bool>, minimized: Option<bool>,
|
||||||
maximized: Option<bool>, minimized: Option<bool>,
|
fullscreen: Option<bool>, output: Option<&wl_output::WlOutput>,
|
||||||
fullscreen: Option<bool>,
|
) where
|
||||||
output: Option<&wl_output::WlOutput>)
|
|
||||||
where
|
|
||||||
U: 'static,
|
U: 'static,
|
||||||
R: Role<ShellSurfaceRole> + 'static,
|
R: Role<ShellSurfaceRole> + 'static,
|
||||||
CID: 'static,
|
CID: 'static,
|
||||||
|
@ -467,11 +467,10 @@ where
|
||||||
send_toplevel_configure(idata.compositor_token, toplevel, configure);
|
send_toplevel_configure(idata.compositor_token, toplevel, configure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn send_toplevel_configure<U, R, ID>(
|
||||||
pub fn send_toplevel_configure<U, R, ID>(token: CompositorToken<U, R, ID>,
|
token: CompositorToken<U, R, ID>, resource: &zxdg_toplevel_v6::ZxdgToplevelV6,
|
||||||
resource: &zxdg_toplevel_v6::ZxdgToplevelV6,
|
configure: ToplevelConfigure,
|
||||||
configure: ToplevelConfigure)
|
) where
|
||||||
where
|
|
||||||
U: 'static,
|
U: 'static,
|
||||||
R: Role<ShellSurfaceRole> + 'static,
|
R: Role<ShellSurfaceRole> + 'static,
|
||||||
ID: 'static,
|
ID: 'static,
|
||||||
|
@ -497,9 +496,9 @@ where
|
||||||
.expect("xdg_toplevel exists but surface has not shell_surface role?!");
|
.expect("xdg_toplevel exists but surface has not shell_surface role?!");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_toplevel_handle<U, R, H, SD>(token: CompositorToken<U, R, H>,
|
fn make_toplevel_handle<U, R, H, SD>(
|
||||||
resource: &zxdg_toplevel_v6::ZxdgToplevelV6)
|
token: CompositorToken<U, R, H>, resource: &zxdg_toplevel_v6::ZxdgToplevelV6
|
||||||
-> super::ToplevelSurface<U, R, H, SD> {
|
) -> super::ToplevelSurface<U, R, H, SD> {
|
||||||
let ptr = resource.get_user_data();
|
let ptr = resource.get_user_data();
|
||||||
let &(ref wl_surface, _, _) = unsafe { &*(ptr as *mut ShellSurfaceUserData) };
|
let &(ref wl_surface, _, _) = unsafe { &*(ptr as *mut ShellSurfaceUserData) };
|
||||||
super::ToplevelSurface {
|
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>(
|
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
|
where
|
||||||
U: 'static,
|
U: 'static,
|
||||||
R: Role<ShellSurfaceRole> + 'static,
|
R: Role<ShellSurfaceRole> + 'static,
|
||||||
|
@ -546,8 +544,9 @@ where
|
||||||
with_surface_toplevel_data(idata, toplevel, |toplevel_data| {
|
with_surface_toplevel_data(idata, toplevel, |toplevel_data| {
|
||||||
toplevel_data.parent = parent.map(|toplevel_surface_parent| {
|
toplevel_data.parent = parent.map(|toplevel_surface_parent| {
|
||||||
let parent_ptr = toplevel_surface_parent.get_user_data();
|
let parent_ptr = toplevel_surface_parent.get_user_data();
|
||||||
let &(ref parent_surface, _) =
|
let &(ref parent_surface, _) = unsafe {
|
||||||
unsafe { &*(parent_ptr as *mut (wl_surface::WlSurface, zxdg_shell_v6::ZxdgShellV6)) };
|
&*(parent_ptr as *mut (wl_surface::WlSurface, zxdg_shell_v6::ZxdgShellV6))
|
||||||
|
};
|
||||||
unsafe { parent_surface.clone_unchecked() }
|
unsafe { parent_surface.clone_unchecked() }
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -620,10 +619,9 @@ fn destroy_popup(surface: &zxdg_popup_v6::ZxdgPopupV6) {
|
||||||
::std::mem::drop(data);
|
::std::mem::drop(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn send_popup_configure<U, R, ID>(token: CompositorToken<U, R, ID>,
|
pub(crate) fn send_popup_configure<U, R, ID>(
|
||||||
resource: &zxdg_popup_v6::ZxdgPopupV6,
|
token: CompositorToken<U, R, ID>, resource: &zxdg_popup_v6::ZxdgPopupV6, configure: PopupConfigure
|
||||||
configure: PopupConfigure)
|
) where
|
||||||
where
|
|
||||||
U: 'static,
|
U: 'static,
|
||||||
R: Role<ShellSurfaceRole> + 'static,
|
R: Role<ShellSurfaceRole> + 'static,
|
||||||
ID: 'static,
|
ID: 'static,
|
||||||
|
@ -641,8 +639,9 @@ where
|
||||||
.expect("xdg_toplevel exists but surface has not shell_surface role?!");
|
.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)
|
fn make_popup_handle<U, R, H, SD>(
|
||||||
-> super::PopupSurface<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 ptr = resource.get_user_data();
|
||||||
let &(ref wl_surface, _, _) = unsafe { &*(ptr as *mut ShellSurfaceUserData) };
|
let &(ref wl_surface, _, _) = unsafe { &*(ptr as *mut ShellSurfaceUserData) };
|
||||||
super::PopupSurface {
|
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>(
|
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
|
where
|
||||||
U: 'static,
|
U: 'static,
|
||||||
R: Role<ShellSurfaceRole> + '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.
|
//! 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 self::pool::{Pool, ResizeError};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -89,8 +88,9 @@ pub struct ShmGlobalData {
|
||||||
/// The global is directly registered into the eventloop, and this function
|
/// The global is directly registered into the eventloop, and this function
|
||||||
/// returns the global handle, in case you whish to remove this global in
|
/// returns the global handle, in case you whish to remove this global in
|
||||||
/// the future.
|
/// the future.
|
||||||
pub fn init_shm_global<L>(evl: &mut EventLoop, mut formats: Vec<wl_shm::Format>, logger: L)
|
pub fn init_shm_global<L>(
|
||||||
-> Global<wl_shm::WlShm, ShmGlobalData>
|
evl: &mut EventLoop, mut formats: Vec<wl_shm::Format>, logger: L
|
||||||
|
) -> Global<wl_shm::WlShm, ShmGlobalData>
|
||||||
where
|
where
|
||||||
L: Into<Option<::slog::Logger>>,
|
L: Into<Option<::slog::Logger>>,
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
use nix::{libc, unistd};
|
use nix::{libc, unistd};
|
||||||
use nix::sys::mman;
|
use nix::sys::mman;
|
||||||
use nix::sys::signal::{self, SigAction, SigHandler, Signal};
|
use nix::sys::signal::{self, SigAction, SigHandler, Signal};
|
||||||
|
|
Loading…
Reference in New Issue