backend: migrate drm & udev
This commit is contained in:
parent
f9dbabce56
commit
7f6af94733
|
@ -37,8 +37,11 @@ pub(crate) struct DrmBackendInternal<A: Device + 'static> {
|
||||||
|
|
||||||
impl<A: Device + 'static> DrmBackend<A> {
|
impl<A: Device + 'static> DrmBackend<A> {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
context: Rc<EGLContext<Gbm<framebuffer::Info>, GbmDevice<A>>>, crtc: crtc::Handle, mode: Mode,
|
context: Rc<EGLContext<Gbm<framebuffer::Info>, GbmDevice<A>>>,
|
||||||
connectors: Vec<connector::Handle>, log: ::slog::Logger,
|
crtc: crtc::Handle,
|
||||||
|
mode: Mode,
|
||||||
|
connectors: Vec<connector::Handle>,
|
||||||
|
log: ::slog::Logger,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
// logger already initialized by the DrmDevice
|
// logger already initialized by the DrmDevice
|
||||||
info!(log, "Initializing DrmBackend");
|
info!(log, "Initializing DrmBackend");
|
||||||
|
@ -351,7 +354,8 @@ impl<A: Device + 'static> DrmBackendInternal<A> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn page_flip(
|
pub(crate) fn page_flip(
|
||||||
&self, fb: Option<&framebuffer::Info>
|
&self,
|
||||||
|
fb: Option<&framebuffer::Info>,
|
||||||
) -> ::std::result::Result<(), SwapBuffersError> {
|
) -> ::std::result::Result<(), SwapBuffersError> {
|
||||||
trace!(self.logger, "Queueing Page flip");
|
trace!(self.logger, "Queueing Page flip");
|
||||||
|
|
||||||
|
@ -421,7 +425,9 @@ impl<A: Device + 'static> GraphicsBackend for DrmBackend<A> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_cursor_representation(
|
fn set_cursor_representation(
|
||||||
&self, buffer: &ImageBuffer<Rgba<u8>, Vec<u8>>, hotspot: (u32, u32)
|
&self,
|
||||||
|
buffer: &ImageBuffer<Rgba<u8>, Vec<u8>>,
|
||||||
|
hotspot: (u32, u32),
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let (w, h) = buffer.dimensions();
|
let (w, h) = buffer.dimensions();
|
||||||
debug!(self.backend.logger, "Importing cursor");
|
debug!(self.backend.logger, "Importing cursor");
|
||||||
|
|
|
@ -233,8 +233,9 @@ use std::rc::{Rc, Weak};
|
||||||
use std::sync::{Arc, Once, ONCE_INIT};
|
use std::sync::{Arc, Once, ONCE_INIT};
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use wayland_server::{Display, EventLoopHandle};
|
use wayland_server::{Display, LoopToken};
|
||||||
use wayland_server::sources::{FdEventSource, FdEventSourceImpl, FdInterest};
|
use wayland_server::commons::{downcast_impl, Implementation};
|
||||||
|
use wayland_server::sources::{FdEvent, FdInterest, Source};
|
||||||
|
|
||||||
mod backend;
|
mod backend;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
@ -378,7 +379,10 @@ impl<A: ControlDevice + 'static> DrmDevice<A> {
|
||||||
/// 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<I>(
|
pub fn create_backend<I>(
|
||||||
&mut self, crtc: crtc::Handle, mode: Mode, connectors: I
|
&mut self,
|
||||||
|
crtc: crtc::Handle,
|
||||||
|
mode: Mode,
|
||||||
|
connectors: I,
|
||||||
) -> Result<DrmBackend<A>>
|
) -> Result<DrmBackend<A>>
|
||||||
where
|
where
|
||||||
I: Into<Vec<connector::Handle>>,
|
I: Into<Vec<connector::Handle>>,
|
||||||
|
@ -532,44 +536,66 @@ impl<A: ControlDevice + 'static> Drop for DrmDevice<A> {
|
||||||
pub trait DrmHandler<A: ControlDevice + 'static> {
|
pub trait DrmHandler<A: ControlDevice + 'static> {
|
||||||
/// The `DrmBackend` of crtc has finished swapping buffers and new frame can now
|
/// The `DrmBackend` of crtc has finished swapping buffers and new frame can now
|
||||||
/// (and should be immediately) be rendered.
|
/// (and should be immediately) be rendered.
|
||||||
fn ready(
|
fn ready(&mut self, device: &mut DrmDevice<A>, crtc: crtc::Handle, frame: u32, duration: Duration);
|
||||||
&mut self, evlh: &mut EventLoopHandle, device: &mut DrmDevice<A>, 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
|
||||||
/// the whole stack has to be recreated..
|
/// the whole stack has to be recreated..
|
||||||
fn error(&mut self, evlh: &mut EventLoopHandle, device: &mut DrmDevice<A>, error: DrmError);
|
fn error(&mut self, device: &mut DrmDevice<A>, error: DrmError);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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<A, H>(
|
pub fn drm_device_bind<A, H>(
|
||||||
evlh: &mut EventLoopHandle, device: DrmDevice<A>, handler: H
|
token: &LoopToken,
|
||||||
) -> ::std::result::Result<FdEventSource<(DrmDevice<A>, H)>, (IoError, (DrmDevice<A>, H))>
|
device: DrmDevice<A>,
|
||||||
|
handler: H,
|
||||||
|
) -> ::std::result::Result<(Source<FdEvent>, Rc<RefCell<DrmDevice<A>>>), (IoError, (DrmDevice<A>, H))>
|
||||||
where
|
where
|
||||||
A: ControlDevice + 'static,
|
A: ControlDevice + 'static,
|
||||||
H: DrmHandler<A> + 'static,
|
H: DrmHandler<A> + 'static,
|
||||||
{
|
{
|
||||||
let fd = device.as_raw_fd();
|
let fd = device.as_raw_fd();
|
||||||
evlh.add_fd_event_source(
|
let device = Rc::new(RefCell::new(device));
|
||||||
|
match token.add_fd_event_source(
|
||||||
fd,
|
fd,
|
||||||
fd_event_source_implementation(),
|
|
||||||
(device, handler),
|
|
||||||
FdInterest::READ,
|
FdInterest::READ,
|
||||||
)
|
DrmFdImpl {
|
||||||
|
device: device.clone(),
|
||||||
|
handler,
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Ok(source) => Ok((source, device)),
|
||||||
|
Err((
|
||||||
|
ioerror,
|
||||||
|
DrmFdImpl {
|
||||||
|
device: device2,
|
||||||
|
handler,
|
||||||
|
},
|
||||||
|
)) => {
|
||||||
|
// make the Rc unique again
|
||||||
|
::std::mem::drop(device2);
|
||||||
|
let device = Rc::try_unwrap(device).unwrap_or_else(|_| unreachable!());
|
||||||
|
Err((ioerror, (device.into_inner(), handler)))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fd_event_source_implementation<A, H>() -> FdEventSourceImpl<(DrmDevice<A>, H)>
|
struct DrmFdImpl<A: ControlDevice + 'static, H> {
|
||||||
|
device: Rc<RefCell<DrmDevice<A>>>,
|
||||||
|
handler: H,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, H> Implementation<(), FdEvent> for DrmFdImpl<A, H>
|
||||||
where
|
where
|
||||||
A: ControlDevice + 'static,
|
A: ControlDevice + 'static,
|
||||||
H: DrmHandler<A> + 'static,
|
H: DrmHandler<A> + 'static,
|
||||||
{
|
{
|
||||||
FdEventSourceImpl {
|
fn receive(&mut self, event: FdEvent, (): ()) {
|
||||||
ready: |evlh, &mut (ref mut device, ref mut handler), _, _| {
|
let mut device = self.device.borrow_mut();
|
||||||
match crtc::receive_events(device) {
|
match event {
|
||||||
|
FdEvent::Ready { .. } => match crtc::receive_events(&mut *device) {
|
||||||
Ok(events) => for event in events {
|
Ok(events) => for event in events {
|
||||||
if let crtc::Event::PageFlip(event) = event {
|
if let crtc::Event::PageFlip(event) = event {
|
||||||
if device.active.load(Ordering::SeqCst) {
|
if device.active.load(Ordering::SeqCst) {
|
||||||
|
@ -584,20 +610,21 @@ where
|
||||||
backend.unlock_buffer();
|
backend.unlock_buffer();
|
||||||
trace!(device.logger, "Handling event for backend {:?}", event.crtc);
|
trace!(device.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(evlh, device, event.crtc, event.frame, event.duration);
|
self.handler
|
||||||
|
.ready(&mut device, event.crtc, event.frame, event.duration);
|
||||||
} else {
|
} else {
|
||||||
device.backends.borrow_mut().remove(&event.crtc);
|
device.backends.borrow_mut().remove(&event.crtc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(err) => handler.error(evlh, device, err),
|
Err(err) => self.handler.error(&mut device, err),
|
||||||
};
|
|
||||||
},
|
},
|
||||||
error: |evlh, &mut (ref mut device, ref mut handler), _, error| {
|
FdEvent::Error { error, .. } => {
|
||||||
warn!(device.logger, "DrmDevice errored: {}", error);
|
warn!(device.logger, "DrmDevice errored: {}", error);
|
||||||
handler.error(evlh, device, error.into());
|
self.handler.error(&mut device, error.into());
|
||||||
},
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -629,7 +656,7 @@ impl<A: ControlDevice + 'static> AsSessionObserver<DrmDeviceObserver<A>> for Drm
|
||||||
|
|
||||||
#[cfg(feature = "backend_session")]
|
#[cfg(feature = "backend_session")]
|
||||||
impl<A: ControlDevice + 'static> SessionObserver for DrmDeviceObserver<A> {
|
impl<A: ControlDevice + 'static> SessionObserver for DrmDeviceObserver<A> {
|
||||||
fn pause(&mut self, _evlh: &mut EventLoopHandle, devnum: Option<(u32, u32)>) {
|
fn pause(&mut self, devnum: Option<(u32, u32)>) {
|
||||||
if let Some((major, minor)) = devnum {
|
if let Some((major, minor)) = devnum {
|
||||||
if major as u64 != stat::major(self.device_id) || minor as u64 != stat::minor(self.device_id) {
|
if major as u64 != stat::major(self.device_id) || minor as u64 != stat::minor(self.device_id) {
|
||||||
return;
|
return;
|
||||||
|
@ -665,7 +692,7 @@ impl<A: ControlDevice + 'static> SessionObserver for DrmDeviceObserver<A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn activate(&mut self, _evlh: &mut EventLoopHandle, devnum: Option<(u32, u32, Option<RawFd>)>) {
|
fn activate(&mut self, devnum: Option<(u32, u32, Option<RawFd>)>) {
|
||||||
if let Some((major, minor, fd)) = devnum {
|
if let Some((major, minor, fd)) = devnum {
|
||||||
if major as u64 != stat::major(self.device_id) || minor as u64 != stat::minor(self.device_id) {
|
if major as u64 != stat::major(self.device_id) || minor as u64 != stat::minor(self.device_id) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -50,7 +50,10 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> DerefMut for EGLContext<B,
|
||||||
impl<B: native::Backend, N: native::NativeDisplay<B>> EGLContext<B, N> {
|
impl<B: native::Backend, N: native::NativeDisplay<B>> EGLContext<B, N> {
|
||||||
/// Create a new `EGLContext` from a given `NativeDisplay`
|
/// Create a new `EGLContext` from a given `NativeDisplay`
|
||||||
pub fn new<L>(
|
pub fn new<L>(
|
||||||
native: N, attributes: GlAttributes, reqs: PixelFormatRequirements, logger: L
|
native: N,
|
||||||
|
attributes: GlAttributes,
|
||||||
|
reqs: PixelFormatRequirements,
|
||||||
|
logger: L,
|
||||||
) -> Result<EGLContext<B, N>>
|
) -> Result<EGLContext<B, N>>
|
||||||
where
|
where
|
||||||
L: Into<Option<::slog::Logger>>,
|
L: Into<Option<::slog::Logger>>,
|
||||||
|
@ -82,7 +85,9 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLContext<B, N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn new_internal(
|
unsafe fn new_internal(
|
||||||
ptr: ffi::NativeDisplayType, mut attributes: GlAttributes, reqs: PixelFormatRequirements,
|
ptr: ffi::NativeDisplayType,
|
||||||
|
mut attributes: GlAttributes,
|
||||||
|
reqs: PixelFormatRequirements,
|
||||||
log: ::slog::Logger,
|
log: ::slog::Logger,
|
||||||
) -> Result<
|
) -> Result<
|
||||||
(
|
(
|
||||||
|
|
|
@ -42,7 +42,8 @@ pub mod egl {
|
||||||
#[allow(non_snake_case, unused_variables, dead_code)]
|
#[allow(non_snake_case, unused_variables, dead_code)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn BindWaylandDisplayWL(
|
pub unsafe fn BindWaylandDisplayWL(
|
||||||
dpy: types::EGLDisplay, display: *mut __gl_imports::raw::c_void
|
dpy: types::EGLDisplay,
|
||||||
|
display: *mut __gl_imports::raw::c_void,
|
||||||
) -> types::EGLBoolean {
|
) -> types::EGLBoolean {
|
||||||
__gl_imports::mem::transmute::<
|
__gl_imports::mem::transmute::<
|
||||||
_,
|
_,
|
||||||
|
@ -53,7 +54,8 @@ pub mod egl {
|
||||||
#[allow(non_snake_case, unused_variables, dead_code)]
|
#[allow(non_snake_case, unused_variables, dead_code)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn UnbindWaylandDisplayWL(
|
pub unsafe fn UnbindWaylandDisplayWL(
|
||||||
dpy: types::EGLDisplay, display: *mut __gl_imports::raw::c_void
|
dpy: types::EGLDisplay,
|
||||||
|
display: *mut __gl_imports::raw::c_void,
|
||||||
) -> types::EGLBoolean {
|
) -> types::EGLBoolean {
|
||||||
__gl_imports::mem::transmute::<
|
__gl_imports::mem::transmute::<
|
||||||
_,
|
_,
|
||||||
|
@ -64,7 +66,9 @@ pub mod egl {
|
||||||
#[allow(non_snake_case, unused_variables, dead_code)]
|
#[allow(non_snake_case, unused_variables, dead_code)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn QueryWaylandBufferWL(
|
pub unsafe fn QueryWaylandBufferWL(
|
||||||
dpy: types::EGLDisplay, buffer: *mut __gl_imports::raw::c_void, attribute: types::EGLint,
|
dpy: types::EGLDisplay,
|
||||||
|
buffer: *mut __gl_imports::raw::c_void,
|
||||||
|
attribute: types::EGLint,
|
||||||
value: *mut types::EGLint,
|
value: *mut types::EGLint,
|
||||||
) -> types::EGLBoolean {
|
) -> types::EGLBoolean {
|
||||||
__gl_imports::mem::transmute::<
|
__gl_imports::mem::transmute::<
|
||||||
|
|
|
@ -31,7 +31,9 @@ pub trait Backend {
|
||||||
/// The returned `EGLDisplay` needs to be a valid ptr for egl,
|
/// The returned `EGLDisplay` needs to be a valid ptr for egl,
|
||||||
/// but there is no way to test that.
|
/// but there is no way to test that.
|
||||||
unsafe fn get_display<F: Fn(&str) -> bool>(
|
unsafe fn get_display<F: Fn(&str) -> bool>(
|
||||||
display: ffi::NativeDisplayType, has_dp_extension: F, log: ::slog::Logger
|
display: ffi::NativeDisplayType,
|
||||||
|
has_dp_extension: F,
|
||||||
|
log: ::slog::Logger,
|
||||||
) -> ffi::egl::types::EGLDisplay;
|
) -> ffi::egl::types::EGLDisplay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +45,9 @@ impl Backend for Wayland {
|
||||||
type Surface = wegl::WlEglSurface;
|
type Surface = wegl::WlEglSurface;
|
||||||
|
|
||||||
unsafe fn get_display<F>(
|
unsafe fn get_display<F>(
|
||||||
display: ffi::NativeDisplayType, has_dp_extension: F, log: ::slog::Logger
|
display: ffi::NativeDisplayType,
|
||||||
|
has_dp_extension: F,
|
||||||
|
log: ::slog::Logger,
|
||||||
) -> ffi::egl::types::EGLDisplay
|
) -> ffi::egl::types::EGLDisplay
|
||||||
where
|
where
|
||||||
F: Fn(&str) -> bool,
|
F: Fn(&str) -> bool,
|
||||||
|
@ -87,7 +91,9 @@ impl Backend for X11 {
|
||||||
type Surface = XlibWindow;
|
type Surface = XlibWindow;
|
||||||
|
|
||||||
unsafe fn get_display<F>(
|
unsafe fn get_display<F>(
|
||||||
display: ffi::NativeDisplayType, has_dp_extension: F, log: ::slog::Logger
|
display: ffi::NativeDisplayType,
|
||||||
|
has_dp_extension: F,
|
||||||
|
log: ::slog::Logger,
|
||||||
) -> ffi::egl::types::EGLDisplay
|
) -> ffi::egl::types::EGLDisplay
|
||||||
where
|
where
|
||||||
F: Fn(&str) -> bool,
|
F: Fn(&str) -> bool,
|
||||||
|
@ -114,7 +120,9 @@ impl<T: 'static> Backend for Gbm<T> {
|
||||||
type Surface = GbmSurface<T>;
|
type Surface = GbmSurface<T>;
|
||||||
|
|
||||||
unsafe fn get_display<F>(
|
unsafe fn get_display<F>(
|
||||||
display: ffi::NativeDisplayType, has_dp_extension: F, log: ::slog::Logger
|
display: ffi::NativeDisplayType,
|
||||||
|
has_dp_extension: F,
|
||||||
|
log: ::slog::Logger,
|
||||||
) -> ffi::egl::types::EGLDisplay
|
) -> ffi::egl::types::EGLDisplay
|
||||||
where
|
where
|
||||||
F: Fn(&str) -> bool,
|
F: Fn(&str) -> bool,
|
||||||
|
|
|
@ -30,7 +30,8 @@ impl<N: native::NativeSurface> DerefMut for EGLSurface<N> {
|
||||||
|
|
||||||
impl<N: native::NativeSurface> EGLSurface<N> {
|
impl<N: native::NativeSurface> EGLSurface<N> {
|
||||||
pub(crate) fn new<B: native::Backend<Surface = N>, D: native::NativeDisplay<B>>(
|
pub(crate) fn new<B: native::Backend<Surface = N>, D: native::NativeDisplay<B>>(
|
||||||
context: &EGLContext<B, D>, native: N
|
context: &EGLContext<B, D>,
|
||||||
|
native: N,
|
||||||
) -> Result<EGLSurface<N>> {
|
) -> Result<EGLSurface<N>> {
|
||||||
let surface = unsafe {
|
let surface = unsafe {
|
||||||
ffi::egl::CreateWindowSurface(
|
ffi::egl::CreateWindowSurface(
|
||||||
|
|
|
@ -192,7 +192,9 @@ impl EGLImages {
|
||||||
///
|
///
|
||||||
/// The given `tex_id` needs to be a valid GL texture otherwise undefined behavior might occur.
|
/// The given `tex_id` needs to be a valid GL texture otherwise undefined behavior might occur.
|
||||||
pub unsafe fn bind_to_texture(
|
pub unsafe fn bind_to_texture(
|
||||||
&self, plane: usize, tex_id: c_uint
|
&self,
|
||||||
|
plane: usize,
|
||||||
|
tex_id: c_uint,
|
||||||
) -> ::std::result::Result<(), TextureCreationError> {
|
) -> ::std::result::Result<(), TextureCreationError> {
|
||||||
if self.display.upgrade().is_some() {
|
if self.display.upgrade().is_some() {
|
||||||
let mut old_tex_id: i32 = 0;
|
let mut old_tex_id: i32 = 0;
|
||||||
|
@ -255,7 +257,8 @@ pub struct EGLDisplay(Weak<ffi::egl::types::EGLDisplay>, *mut wl_display);
|
||||||
|
|
||||||
impl EGLDisplay {
|
impl EGLDisplay {
|
||||||
fn new<B: native::Backend, N: native::NativeDisplay<B>>(
|
fn new<B: native::Backend, N: native::NativeDisplay<B>>(
|
||||||
context: &EGLContext<B, N>, display: *mut wl_display
|
context: &EGLContext<B, N>,
|
||||||
|
display: *mut wl_display,
|
||||||
) -> EGLDisplay {
|
) -> EGLDisplay {
|
||||||
EGLDisplay(Rc::downgrade(&context.display), display)
|
EGLDisplay(Rc::downgrade(&context.display), display)
|
||||||
}
|
}
|
||||||
|
@ -266,7 +269,8 @@ impl EGLDisplay {
|
||||||
/// a `BufferAccessError::NotManaged(WlBuffer)` is returned with the original buffer
|
/// a `BufferAccessError::NotManaged(WlBuffer)` is returned with the original buffer
|
||||||
/// to render it another way.
|
/// to render it another way.
|
||||||
pub fn egl_buffer_contents(
|
pub fn egl_buffer_contents(
|
||||||
&self, buffer: Resource<WlBuffer>
|
&self,
|
||||||
|
buffer: Resource<WlBuffer>,
|
||||||
) -> ::std::result::Result<EGLImages, BufferAccessError> {
|
) -> ::std::result::Result<EGLImages, BufferAccessError> {
|
||||||
if let Some(display) = self.0.upgrade() {
|
if let Some(display) = self.0.upgrade() {
|
||||||
let mut format: i32 = 0;
|
let mut format: i32 = 0;
|
||||||
|
|
|
@ -30,7 +30,9 @@ pub trait GraphicsBackend {
|
||||||
/// 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(
|
fn set_cursor_representation(
|
||||||
&self, cursor: &Self::CursorFormat, hotspot: (u32, u32)
|
&self,
|
||||||
|
cursor: &Self::CursorFormat,
|
||||||
|
hotspot: (u32, u32),
|
||||||
) -> Result<(), Self::Error>;
|
) -> Result<(), Self::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,11 +19,11 @@ pub mod graphics;
|
||||||
|
|
||||||
//#[cfg(feature = "backend_winit")]
|
//#[cfg(feature = "backend_winit")]
|
||||||
//pub mod winit;
|
//pub mod winit;
|
||||||
//#[cfg(feature = "backend_drm")]
|
#[cfg(feature = "backend_drm")]
|
||||||
//pub mod drm;
|
pub mod drm;
|
||||||
//#[cfg(feature = "backend_libinput")]
|
//#[cfg(feature = "backend_libinput")]
|
||||||
//pub mod libinput;
|
//pub mod libinput;
|
||||||
#[cfg(feature = "backend_session")]
|
#[cfg(feature = "backend_session")]
|
||||||
pub mod session;
|
pub mod session;
|
||||||
//#[cfg(feature = "backend_udev")]
|
#[cfg(feature = "backend_udev")]
|
||||||
//pub mod udev;
|
pub mod udev;
|
||||||
|
|
|
@ -451,11 +451,7 @@ pub fn logind_session_bind(
|
||||||
let mut interest = FdInterest::empty();
|
let mut interest = FdInterest::empty();
|
||||||
interest.set(FdInterest::READ, watch.readable());
|
interest.set(FdInterest::READ, watch.readable());
|
||||||
interest.set(FdInterest::WRITE, watch.writable());
|
interest.set(FdInterest::WRITE, watch.writable());
|
||||||
token.add_fd_event_source(
|
token.add_fd_event_source(watch.fd(), interest, notifier.clone())
|
||||||
watch.fd(),
|
|
||||||
interest,
|
|
||||||
notifier.clone(),
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
.collect::<::std::result::Result<Vec<Source<FdEvent>>, (IoError, _)>>()
|
.collect::<::std::result::Result<Vec<Source<FdEvent>>, (IoError, _)>>()
|
||||||
.map_err(|(err, _)| {
|
.map_err(|(err, _)| {
|
||||||
|
|
|
@ -24,8 +24,9 @@ use std::os::unix::io::{AsRawFd, RawFd};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::rc::{Rc, Weak};
|
use std::rc::{Rc, Weak};
|
||||||
use udev::{Context, Enumerator, Event, EventType, MonitorBuilder, MonitorSocket, Result as UdevResult};
|
use udev::{Context, Enumerator, Event, EventType, MonitorBuilder, MonitorSocket, Result as UdevResult};
|
||||||
use wayland_server::EventLoopHandle;
|
use wayland_server::LoopToken;
|
||||||
use wayland_server::sources::{EventSource, FdEventSource, FdEventSourceImpl, FdInterest};
|
use wayland_server::commons::Implementation;
|
||||||
|
use wayland_server::sources::{FdEvent, FdInterest, Source};
|
||||||
|
|
||||||
/// Udev's `DrmDevice` type based on the underlying session
|
/// Udev's `DrmDevice` type based on the underlying session
|
||||||
pub struct SessionFdDrmDevice(RawFd);
|
pub struct SessionFdDrmDevice(RawFd);
|
||||||
|
@ -48,11 +49,13 @@ pub struct UdevBackend<
|
||||||
S: Session + 'static,
|
S: Session + 'static,
|
||||||
T: UdevHandler<H> + 'static,
|
T: UdevHandler<H> + 'static,
|
||||||
> {
|
> {
|
||||||
devices: Rc<RefCell<HashMap<dev_t, FdEventSource<(DrmDevice<SessionFdDrmDevice>, H)>>>>,
|
_handler: ::std::marker::PhantomData<H>,
|
||||||
|
devices: Rc<RefCell<HashMap<dev_t, (Source<FdEvent>, Rc<RefCell<DrmDevice<SessionFdDrmDevice>>>)>>>,
|
||||||
monitor: MonitorSocket,
|
monitor: MonitorSocket,
|
||||||
session: S,
|
session: S,
|
||||||
handler: T,
|
handler: T,
|
||||||
logger: ::slog::Logger,
|
logger: ::slog::Logger,
|
||||||
|
token: LoopToken,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H: DrmHandler<SessionFdDrmDevice> + 'static, S: Session + 'static, T: UdevHandler<H> + 'static>
|
impl<H: DrmHandler<SessionFdDrmDevice> + 'static, S: Session + 'static, T: UdevHandler<H> + 'static>
|
||||||
|
@ -67,7 +70,11 @@ impl<H: DrmHandler<SessionFdDrmDevice> + 'static, S: Session + 'static, T: UdevH
|
||||||
/// `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>(
|
pub fn new<'a, L>(
|
||||||
mut evlh: &mut EventLoopHandle, context: &Context, mut session: S, mut handler: T, logger: L
|
token: LoopToken,
|
||||||
|
context: &Context,
|
||||||
|
mut session: S,
|
||||||
|
mut handler: T,
|
||||||
|
logger: L,
|
||||||
) -> Result<UdevBackend<H, S, T>>
|
) -> Result<UdevBackend<H, S, T>>
|
||||||
where
|
where
|
||||||
L: Into<Option<::slog::Logger>>,
|
L: Into<Option<::slog::Logger>>,
|
||||||
|
@ -81,7 +88,7 @@ impl<H: DrmHandler<SessionFdDrmDevice> + 'static, S: Session + 'static, T: UdevH
|
||||||
.flat_map(|path| {
|
.flat_map(|path| {
|
||||||
match DrmDevice::new(
|
match DrmDevice::new(
|
||||||
{
|
{
|
||||||
match session.open(&path, fcntl::O_RDWR | fcntl::O_CLOEXEC | fcntl::O_NOCTTY | fcntl::O_NONBLOCK) {
|
match session.open(&path, fcntl::OFlag::O_RDWR | fcntl::OFlag::O_CLOEXEC | fcntl::OFlag::O_NOCTTY | fcntl::OFlag::O_NONBLOCK) {
|
||||||
Ok(fd) => SessionFdDrmDevice(fd),
|
Ok(fd) => SessionFdDrmDevice(fd),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!(logger, "Unable to open drm device {:?}, Error: {:?}. Skipping", path, err);
|
warn!(logger, "Unable to open drm device {:?}, Error: {:?}. Skipping", path, err);
|
||||||
|
@ -94,13 +101,13 @@ impl<H: DrmHandler<SessionFdDrmDevice> + 'static, S: Session + 'static, T: UdevH
|
||||||
Ok(mut device) => {
|
Ok(mut device) => {
|
||||||
let devnum = device.device_id();
|
let devnum = device.device_id();
|
||||||
let fd = device.as_raw_fd();
|
let fd = device.as_raw_fd();
|
||||||
match handler.device_added(evlh, &mut device) {
|
match handler.device_added(&mut device) {
|
||||||
Some(drm_handler) => {
|
Some(drm_handler) => {
|
||||||
match drm_device_bind(&mut evlh, device, drm_handler) {
|
match drm_device_bind(&token, device, drm_handler) {
|
||||||
Ok(event_source) => Some((devnum, event_source)),
|
Ok((event_source, device)) => Some((devnum, (event_source, device))),
|
||||||
Err((err, (mut device, _))) => {
|
Err((err, (mut device, _))) => {
|
||||||
warn!(logger, "Failed to bind device. Error: {:?}.", err);
|
warn!(logger, "Failed to bind device. Error: {:?}.", err);
|
||||||
handler.device_removed(evlh, &mut device);
|
handler.device_removed(&mut device);
|
||||||
drop(device);
|
drop(device);
|
||||||
if let Err(err) = session.close(fd) {
|
if let Err(err) = session.close(fd) {
|
||||||
warn!(logger, "Failed to close dropped device. Error: {:?}. Ignoring", err);
|
warn!(logger, "Failed to close dropped device. Error: {:?}. Ignoring", err);
|
||||||
|
@ -124,7 +131,7 @@ impl<H: DrmHandler<SessionFdDrmDevice> + 'static, S: Session + 'static, T: UdevH
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<HashMap<dev_t, FdEventSource<(DrmDevice<SessionFdDrmDevice>, H)>>>();
|
.collect::<HashMap<dev_t, _>>();
|
||||||
|
|
||||||
let mut builder = MonitorBuilder::new(context).chain_err(|| ErrorKind::FailedToInitMonitor)?;
|
let mut builder = MonitorBuilder::new(context).chain_err(|| ErrorKind::FailedToInitMonitor)?;
|
||||||
builder
|
builder
|
||||||
|
@ -135,20 +142,25 @@ impl<H: DrmHandler<SessionFdDrmDevice> + 'static, S: Session + 'static, T: UdevH
|
||||||
.chain_err(|| ErrorKind::FailedToInitMonitor)?;
|
.chain_err(|| ErrorKind::FailedToInitMonitor)?;
|
||||||
|
|
||||||
Ok(UdevBackend {
|
Ok(UdevBackend {
|
||||||
|
_handler: ::std::marker::PhantomData,
|
||||||
devices: Rc::new(RefCell::new(devices)),
|
devices: Rc::new(RefCell::new(devices)),
|
||||||
monitor,
|
monitor,
|
||||||
session,
|
session,
|
||||||
handler,
|
handler,
|
||||||
logger,
|
logger,
|
||||||
|
token,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Closes the udev backend and frees all remaining open devices.
|
/// Closes the udev backend and frees all remaining open devices.
|
||||||
pub fn close(&mut self, evlh: &mut EventLoopHandle) {
|
pub fn close(&mut self) {
|
||||||
let mut devices = self.devices.borrow_mut();
|
let mut devices = self.devices.borrow_mut();
|
||||||
for (_, event_source) in devices.drain() {
|
for (_, (event_source, device)) in devices.drain() {
|
||||||
let (mut device, _) = event_source.remove();
|
event_source.remove();
|
||||||
self.handler.device_removed(evlh, &mut device);
|
let mut device = Rc::try_unwrap(device)
|
||||||
|
.unwrap_or_else(|_| unreachable!())
|
||||||
|
.into_inner();
|
||||||
|
self.handler.device_removed(&mut device);
|
||||||
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) {
|
||||||
|
@ -163,8 +175,8 @@ impl<H: DrmHandler<SessionFdDrmDevice> + 'static, S: Session + 'static, T: UdevH
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `SessionObserver` linked to the `UdevBackend` it was created from.
|
/// `SessionObserver` linked to the `UdevBackend` it was created from.
|
||||||
pub struct UdevBackendObserver<H: DrmHandler<SessionFdDrmDevice> + 'static> {
|
pub struct UdevBackendObserver {
|
||||||
devices: Weak<RefCell<HashMap<dev_t, FdEventSource<(DrmDevice<SessionFdDrmDevice>, H)>>>>,
|
devices: Weak<RefCell<HashMap<dev_t, (Source<FdEvent>, Rc<RefCell<DrmDevice<SessionFdDrmDevice>>>)>>>,
|
||||||
logger: ::slog::Logger,
|
logger: ::slog::Logger,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,9 +184,9 @@ impl<
|
||||||
H: DrmHandler<SessionFdDrmDevice> + 'static,
|
H: DrmHandler<SessionFdDrmDevice> + 'static,
|
||||||
S: Session + 'static,
|
S: Session + 'static,
|
||||||
T: UdevHandler<H> + 'static,
|
T: UdevHandler<H> + 'static,
|
||||||
> AsSessionObserver<UdevBackendObserver<H>> for UdevBackend<H, S, T>
|
> AsSessionObserver<UdevBackendObserver> for UdevBackend<H, S, T>
|
||||||
{
|
{
|
||||||
fn observer(&mut self) -> UdevBackendObserver<H> {
|
fn observer(&mut self) -> UdevBackendObserver {
|
||||||
UdevBackendObserver {
|
UdevBackendObserver {
|
||||||
devices: Rc::downgrade(&self.devices),
|
devices: Rc::downgrade(&self.devices),
|
||||||
logger: self.logger.clone(),
|
logger: self.logger.clone(),
|
||||||
|
@ -182,25 +194,21 @@ impl<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H: DrmHandler<SessionFdDrmDevice> + 'static> SessionObserver for UdevBackendObserver<H> {
|
impl SessionObserver for UdevBackendObserver {
|
||||||
fn pause<'a>(&mut self, evlh: &mut EventLoopHandle, devnum: Option<(u32, u32)>) {
|
fn pause<'a>(&mut self, devnum: Option<(u32, u32)>) {
|
||||||
if let Some(devices) = self.devices.upgrade() {
|
if let Some(devices) = self.devices.upgrade() {
|
||||||
for fd_event_source in devices.borrow_mut().values_mut() {
|
for &mut (_, ref device) in devices.borrow_mut().values_mut() {
|
||||||
fd_event_source.with_idata(evlh, |&mut (ref mut device, _), evlh| {
|
|
||||||
info!(self.logger, "changed successful");
|
info!(self.logger, "changed successful");
|
||||||
device.observer().pause(evlh, devnum);
|
device.borrow_mut().observer().pause(devnum);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn activate<'a>(&mut self, evlh: &mut EventLoopHandle, devnum: Option<(u32, u32, Option<RawFd>)>) {
|
fn activate<'a>(&mut self, devnum: Option<(u32, u32, Option<RawFd>)>) {
|
||||||
if let Some(devices) = self.devices.upgrade() {
|
if let Some(devices) = self.devices.upgrade() {
|
||||||
for fd_event_source in devices.borrow_mut().values_mut() {
|
for &mut (_, ref device) in devices.borrow_mut().values_mut() {
|
||||||
fd_event_source.with_idata(evlh, |&mut (ref mut device, _), evlh| {
|
|
||||||
info!(self.logger, "changed successful");
|
info!(self.logger, "changed successful");
|
||||||
device.observer().activate(evlh, devnum);
|
device.borrow_mut().observer().activate(devnum);
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,41 +218,44 @@ impl<H: DrmHandler<SessionFdDrmDevice> + 'static> SessionObserver for UdevBacken
|
||||||
///
|
///
|
||||||
/// 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<S, H, T>(
|
pub fn udev_backend_bind<H, S, T>(
|
||||||
evlh: &mut EventLoopHandle, udev: UdevBackend<H, S, T>
|
token: &LoopToken,
|
||||||
) -> ::std::result::Result<FdEventSource<UdevBackend<H, S, T>>, (IoError, UdevBackend<H, S, T>)>
|
udev: UdevBackend<H, S, T>,
|
||||||
|
) -> ::std::result::Result<Source<FdEvent>, (IoError, UdevBackend<H, S, T>)>
|
||||||
where
|
where
|
||||||
H: DrmHandler<SessionFdDrmDevice> + 'static,
|
H: DrmHandler<SessionFdDrmDevice> + 'static,
|
||||||
T: UdevHandler<H> + 'static,
|
T: UdevHandler<H> + 'static,
|
||||||
S: Session + 'static,
|
S: Session + 'static,
|
||||||
{
|
{
|
||||||
let fd = udev.monitor.as_raw_fd();
|
let fd = udev.monitor.as_raw_fd();
|
||||||
evlh.add_fd_event_source(fd, fd_event_source_implementation(), udev, FdInterest::READ)
|
token.add_fd_event_source(fd, FdInterest::READ, udev)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fd_event_source_implementation<S, H, T>() -> FdEventSourceImpl<UdevBackend<H, S, T>>
|
impl<H, S, T> Implementation<(), FdEvent> for UdevBackend<H, S, T>
|
||||||
where
|
where
|
||||||
H: DrmHandler<SessionFdDrmDevice> + 'static,
|
H: DrmHandler<SessionFdDrmDevice> + 'static,
|
||||||
T: UdevHandler<H> + 'static,
|
T: UdevHandler<H> + 'static,
|
||||||
S: Session + 'static,
|
S: Session + 'static,
|
||||||
{
|
{
|
||||||
FdEventSourceImpl {
|
fn receive(&mut self, event: FdEvent, (): ()) {
|
||||||
ready: |mut evlh, udev, _, _| {
|
match event {
|
||||||
let events = udev.monitor.clone().collect::<Vec<Event>>();
|
FdEvent::Ready { .. } => {
|
||||||
|
let events = self.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
|
||||||
EventType::Add => {
|
EventType::Add => {
|
||||||
info!(udev.logger, "Device Added");
|
info!(self.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 DrmDevice::new(
|
match DrmDevice::new(
|
||||||
{
|
{
|
||||||
let logger = udev.logger.clone();
|
let logger = self.logger.clone();
|
||||||
match udev.session.open(
|
match self.session.open(
|
||||||
path,
|
path,
|
||||||
fcntl::O_RDWR | fcntl::O_CLOEXEC | fcntl::O_NOCTTY
|
fcntl::OFlag::O_RDWR | fcntl::OFlag::O_CLOEXEC
|
||||||
| fcntl::O_NONBLOCK,
|
| fcntl::OFlag::O_NOCTTY
|
||||||
|
| fcntl::OFlag::O_NONBLOCK,
|
||||||
) {
|
) {
|
||||||
Ok(fd) => SessionFdDrmDevice(fd),
|
Ok(fd) => SessionFdDrmDevice(fd),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -258,12 +269,12 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
udev.logger.clone(),
|
self.logger.clone(),
|
||||||
) {
|
) {
|
||||||
Ok(dev) => dev,
|
Ok(dev) => dev,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!(
|
warn!(
|
||||||
udev.logger,
|
self.logger,
|
||||||
"Failed to initialize device {:?}. Error: {}. Skipping",
|
"Failed to initialize device {:?}. Error: {}. Skipping",
|
||||||
path,
|
path,
|
||||||
err
|
err
|
||||||
|
@ -273,29 +284,34 @@ where
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let fd = device.as_raw_fd();
|
let fd = device.as_raw_fd();
|
||||||
match udev.handler.device_added(evlh, &mut device) {
|
match self.handler.device_added(&mut device) {
|
||||||
Some(drm_handler) => match drm_device_bind(&mut evlh, device, drm_handler) {
|
Some(drm_handler) => {
|
||||||
|
match drm_device_bind(&self.token, device, drm_handler) {
|
||||||
Ok(fd_event_source) => {
|
Ok(fd_event_source) => {
|
||||||
udev.devices.borrow_mut().insert(devnum, fd_event_source);
|
self.devices.borrow_mut().insert(devnum, fd_event_source);
|
||||||
}
|
}
|
||||||
Err((err, (mut device, _))) => {
|
Err((err, (mut device, _))) => {
|
||||||
warn!(udev.logger, "Failed to bind device. Error: {:?}.", err);
|
|
||||||
udev.handler.device_removed(evlh, &mut device);
|
|
||||||
drop(device);
|
|
||||||
if let Err(err) = udev.session.close(fd) {
|
|
||||||
warn!(
|
warn!(
|
||||||
udev.logger,
|
self.logger,
|
||||||
|
"Failed to bind device. Error: {:?}.", err
|
||||||
|
);
|
||||||
|
self.handler.device_removed(&mut device);
|
||||||
|
drop(device);
|
||||||
|
if let Err(err) = self.session.close(fd) {
|
||||||
|
warn!(
|
||||||
|
self.logger,
|
||||||
"Failed to close dropped device. Error: {:?}. Ignoring", err
|
"Failed to close dropped device. Error: {:?}. Ignoring", err
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
}
|
||||||
None => {
|
None => {
|
||||||
udev.handler.device_removed(evlh, &mut device);
|
self.handler.device_removed(&mut device);
|
||||||
drop(device);
|
drop(device);
|
||||||
if let Err(err) = udev.session.close(fd) {
|
if let Err(err) = self.session.close(fd) {
|
||||||
warn!(
|
warn!(
|
||||||
udev.logger,
|
self.logger,
|
||||||
"Failed to close unused device. Error: {:?}", err
|
"Failed to close unused device. Error: {:?}", err
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -305,16 +321,21 @@ where
|
||||||
}
|
}
|
||||||
// Device removed
|
// Device removed
|
||||||
EventType::Remove => {
|
EventType::Remove => {
|
||||||
info!(udev.logger, "Device Remove");
|
info!(self.logger, "Device Remove");
|
||||||
if let Some(devnum) = event.devnum() {
|
if let Some(devnum) = event.devnum() {
|
||||||
if let Some(fd_event_source) = udev.devices.borrow_mut().remove(&devnum) {
|
if let Some((fd_event_source, device)) =
|
||||||
let (mut device, _) = fd_event_source.remove();
|
self.devices.borrow_mut().remove(&devnum)
|
||||||
udev.handler.device_removed(evlh, &mut device);
|
{
|
||||||
|
fd_event_source.remove();
|
||||||
|
let mut device = Rc::try_unwrap(device)
|
||||||
|
.unwrap_or_else(|_| unreachable!())
|
||||||
|
.into_inner();
|
||||||
|
self.handler.device_removed(&mut 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) = self.session.close(fd) {
|
||||||
warn!(
|
warn!(
|
||||||
udev.logger,
|
self.logger,
|
||||||
"Failed to close device {:?}. Error: {:?}. Ignoring",
|
"Failed to close device {:?}. Error: {:?}. Ignoring",
|
||||||
event.sysname(),
|
event.sysname(),
|
||||||
err
|
err
|
||||||
|
@ -325,28 +346,26 @@ where
|
||||||
}
|
}
|
||||||
// New connector
|
// New connector
|
||||||
EventType::Change => {
|
EventType::Change => {
|
||||||
info!(udev.logger, "Device Changed");
|
info!(self.logger, "Device Changed");
|
||||||
if let Some(devnum) = event.devnum() {
|
if let Some(devnum) = event.devnum() {
|
||||||
info!(udev.logger, "Devnum: {:b}", devnum);
|
info!(self.logger, "Devnum: {:b}", devnum);
|
||||||
if let Some(fd_event_source) = udev.devices.borrow_mut().get_mut(&devnum) {
|
if let Some(&(_, ref device)) = self.devices.borrow_mut().get(&devnum) {
|
||||||
let handler = &mut udev.handler;
|
let handler = &mut self.handler;
|
||||||
let logger = &udev.logger;
|
let logger = &self.logger;
|
||||||
fd_event_source.with_idata(evlh, move |&mut (ref mut device, _), evlh| {
|
handler.device_changed(&mut device.borrow_mut());
|
||||||
info!(logger, "changed successful");
|
|
||||||
handler.device_changed(evlh, device);
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
info!(udev.logger, "changed, but device not tracked by backend");
|
info!(self.logger, "changed, but device not tracked by backend");
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
info!(udev.logger, "changed, but no devnum");
|
info!(self.logger, "changed, but no devnum");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
error: |evlh, udev, _, err| udev.handler.error(evlh, err),
|
FdEvent::Error { error, .. } => self.handler.error(error),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,9 +377,7 @@ pub trait UdevHandler<H: DrmHandler<SessionFdDrmDevice> + 'static> {
|
||||||
///
|
///
|
||||||
/// ## 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(
|
fn device_added(&mut self, device: &mut DrmDevice<SessionFdDrmDevice>) -> Option<H>;
|
||||||
&mut self, evlh: &mut EventLoopHandle, device: &mut DrmDevice<SessionFdDrmDevice>
|
|
||||||
) -> 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
|
||||||
|
@ -368,7 +385,7 @@ pub trait UdevHandler<H: DrmHandler<SessionFdDrmDevice> + 'static> {
|
||||||
///
|
///
|
||||||
/// ## 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_changed(&mut self, evlh: &mut EventLoopHandle, device: &mut DrmDevice<SessionFdDrmDevice>);
|
fn device_changed(&mut self, device: &mut DrmDevice<SessionFdDrmDevice>);
|
||||||
/// Called when a device was removed.
|
/// Called when a device was removed.
|
||||||
///
|
///
|
||||||
/// The device will not accept any operations anymore and its file descriptor will be closed once
|
/// The device will not accept any operations anymore and its file descriptor will be closed once
|
||||||
|
@ -376,12 +393,12 @@ pub trait UdevHandler<H: DrmHandler<SessionFdDrmDevice> + 'static> {
|
||||||
///
|
///
|
||||||
/// ## 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_removed(&mut self, evlh: &mut EventLoopHandle, device: &mut DrmDevice<SessionFdDrmDevice>);
|
fn device_removed(&mut self, device: &mut DrmDevice<SessionFdDrmDevice>);
|
||||||
/// Called when the udev context has encountered and error.
|
/// Called when the udev context has encountered and error.
|
||||||
///
|
///
|
||||||
/// ## 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 error(&mut self, evlh: &mut EventLoopHandle, error: IoError);
|
fn error(&mut self, error: IoError);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the path of the primary gpu device if any
|
/// Returns the path of the primary gpu device if any
|
||||||
|
|
Loading…
Reference in New Issue