Update to calloop 0.8, DrmDevice as an EventSource
This commit is contained in:
parent
e008360bde
commit
aaa6e625e9
|
@ -12,7 +12,7 @@ members = [ "anvil" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = "1"
|
bitflags = "1"
|
||||||
calloop = "0.6.2"
|
calloop = {version = "0.8.0" }
|
||||||
cgmath = "0.18.0"
|
cgmath = "0.18.0"
|
||||||
dbus = { version = "0.9.0", optional = true }
|
dbus = { version = "0.9.0", optional = true }
|
||||||
drm-fourcc = "^2.1.1"
|
drm-fourcc = "^2.1.1"
|
||||||
|
@ -35,7 +35,7 @@ wayland-egl = { version = "0.28", optional = true }
|
||||||
wayland-protocols = { version = "0.28", features = ["unstable_protocols", "server"], optional = true }
|
wayland-protocols = { version = "0.28", features = ["unstable_protocols", "server"], optional = true }
|
||||||
wayland-server = { version = "0.28.3", optional = true }
|
wayland-server = { version = "0.28.3", optional = true }
|
||||||
wayland-sys = { version = "0.28", optional = true }
|
wayland-sys = { version = "0.28", optional = true }
|
||||||
winit = { version = "0.24.0", optional = true }
|
winit = { version = "0.25.0", optional = true }
|
||||||
xkbcommon = "0.4.0"
|
xkbcommon = "0.4.0"
|
||||||
scan_fmt = { version = "0.2", default-features = false }
|
scan_fmt = { version = "0.2", default-features = false }
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ use smithay::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl AnvilState {
|
impl<Backend> AnvilState<Backend> {
|
||||||
pub fn process_input_event<B: InputBackend>(&mut self, event: InputEvent<B>) {
|
pub fn process_input_event<B: InputBackend>(&mut self, event: InputEvent<B>) {
|
||||||
match event {
|
match event {
|
||||||
InputEvent::Keyboard { event, .. } => self.on_keyboard_key::<B>(event),
|
InputEvent::Keyboard { event, .. } => self.on_keyboard_key::<B>(event),
|
||||||
|
|
|
@ -39,14 +39,13 @@ fn main() {
|
||||||
o!(),
|
o!(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut event_loop = EventLoop::<AnvilState>::new().unwrap();
|
|
||||||
let display = Rc::new(RefCell::new(Display::new()));
|
|
||||||
|
|
||||||
let arg = ::std::env::args().nth(1);
|
let arg = ::std::env::args().nth(1);
|
||||||
match arg.as_ref().map(|s| &s[..]) {
|
match arg.as_ref().map(|s| &s[..]) {
|
||||||
#[cfg(feature = "winit")]
|
#[cfg(feature = "winit")]
|
||||||
Some("--winit") => {
|
Some("--winit") => {
|
||||||
info!(log, "Starting anvil with winit backend");
|
info!(log, "Starting anvil with winit backend");
|
||||||
|
let mut event_loop = EventLoop::try_new().unwrap();
|
||||||
|
let display = Rc::new(RefCell::new(Display::new()));
|
||||||
if let Err(()) = winit::run_winit(display, &mut event_loop, log.clone()) {
|
if let Err(()) = winit::run_winit(display, &mut event_loop, log.clone()) {
|
||||||
crit!(log, "Failed to initialize winit backend.");
|
crit!(log, "Failed to initialize winit backend.");
|
||||||
}
|
}
|
||||||
|
@ -54,6 +53,8 @@ fn main() {
|
||||||
#[cfg(feature = "udev")]
|
#[cfg(feature = "udev")]
|
||||||
Some("--tty-udev") => {
|
Some("--tty-udev") => {
|
||||||
info!(log, "Starting anvil on a tty using udev");
|
info!(log, "Starting anvil on a tty using udev");
|
||||||
|
let mut event_loop = EventLoop::try_new().unwrap();
|
||||||
|
let display = Rc::new(RefCell::new(Display::new()));
|
||||||
if let Err(()) = udev::run_udev(display, &mut event_loop, log.clone()) {
|
if let Err(()) = udev::run_udev(display, &mut event_loop, log.clone()) {
|
||||||
crit!(log, "Failed to initialize tty backend.");
|
crit!(log, "Failed to initialize tty backend.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,7 @@ use std::{
|
||||||
|
|
||||||
use smithay::{
|
use smithay::{
|
||||||
reexports::{
|
reexports::{
|
||||||
calloop::{
|
calloop::{generic::Generic, Interest, LoopHandle, Mode, RegistrationToken},
|
||||||
generic::{Fd, Generic},
|
|
||||||
Interest, LoopHandle, Mode, Source,
|
|
||||||
},
|
|
||||||
wayland_server::{protocol::wl_surface::WlSurface, Display},
|
wayland_server::{protocol::wl_surface::WlSurface, Display},
|
||||||
},
|
},
|
||||||
wayland::{
|
wayland::{
|
||||||
|
@ -36,11 +33,12 @@ use crate::udev::MyOutput;
|
||||||
#[cfg(feature = "xwayland")]
|
#[cfg(feature = "xwayland")]
|
||||||
use crate::xwayland::XWm;
|
use crate::xwayland::XWm;
|
||||||
|
|
||||||
pub struct AnvilState {
|
pub struct AnvilState<Backend> {
|
||||||
|
pub backend: Backend,
|
||||||
pub socket_name: String,
|
pub socket_name: String,
|
||||||
pub running: Arc<AtomicBool>,
|
pub running: Arc<AtomicBool>,
|
||||||
pub display: Rc<RefCell<Display>>,
|
pub display: Rc<RefCell<Display>>,
|
||||||
pub handle: LoopHandle<AnvilState>,
|
pub handle: LoopHandle<'static, AnvilState<Backend>>,
|
||||||
pub ctoken: CompositorToken<crate::shell::Roles>,
|
pub ctoken: CompositorToken<crate::shell::Roles>,
|
||||||
pub window_map: Rc<RefCell<crate::window_map::WindowMap<crate::shell::Roles>>>,
|
pub window_map: Rc<RefCell<crate::window_map::WindowMap<crate::shell::Roles>>>,
|
||||||
pub dnd_icon: Arc<Mutex<Option<WlSurface>>>,
|
pub dnd_icon: Arc<Mutex<Option<WlSurface>>>,
|
||||||
|
@ -56,30 +54,30 @@ pub struct AnvilState {
|
||||||
#[cfg(feature = "udev")]
|
#[cfg(feature = "udev")]
|
||||||
pub session: Option<AutoSession>,
|
pub session: Option<AutoSession>,
|
||||||
// things we must keep alive
|
// things we must keep alive
|
||||||
_wayland_event_source: Source<Generic<Fd>>,
|
_wayland_event_source: RegistrationToken,
|
||||||
#[cfg(feature = "xwayland")]
|
#[cfg(feature = "xwayland")]
|
||||||
_xwayland: XWayland<XWm>,
|
_xwayland: XWayland<XWm<Backend>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AnvilState {
|
impl<Backend: Default + 'static> AnvilState<Backend> {
|
||||||
pub fn init(
|
pub fn init(
|
||||||
display: Rc<RefCell<Display>>,
|
display: Rc<RefCell<Display>>,
|
||||||
handle: LoopHandle<AnvilState>,
|
handle: LoopHandle<'static, AnvilState<Backend>>,
|
||||||
#[cfg(feature = "egl")] egl_reader: Rc<RefCell<Option<EGLBufferReader>>>,
|
#[cfg(feature = "egl")] egl_reader: Rc<RefCell<Option<EGLBufferReader>>>,
|
||||||
#[cfg(feature = "udev")] session: Option<AutoSession>,
|
#[cfg(feature = "udev")] session: Option<AutoSession>,
|
||||||
#[cfg(not(feature = "udev"))] _session: Option<()>,
|
#[cfg(not(feature = "udev"))] _session: Option<()>,
|
||||||
#[cfg(feature = "udev")] output_map: Option<Rc<RefCell<Vec<MyOutput>>>>,
|
#[cfg(feature = "udev")] output_map: Option<Rc<RefCell<Vec<MyOutput>>>>,
|
||||||
#[cfg(not(feature = "udev"))] _output_map: Option<()>,
|
#[cfg(not(feature = "udev"))] _output_map: Option<()>,
|
||||||
log: slog::Logger,
|
log: slog::Logger,
|
||||||
) -> AnvilState {
|
) -> AnvilState<Backend> {
|
||||||
// init the wayland connection
|
// init the wayland connection
|
||||||
let _wayland_event_source = handle
|
let _wayland_event_source = handle
|
||||||
.insert_source(
|
.insert_source(
|
||||||
Generic::from_fd(display.borrow().get_poll_fd(), Interest::Readable, Mode::Level),
|
Generic::from_fd(display.borrow().get_poll_fd(), Interest::READ, Mode::Level),
|
||||||
{
|
{
|
||||||
let display = display.clone();
|
let display = display.clone();
|
||||||
let log = log.clone();
|
let log = log.clone();
|
||||||
move |_, _, state: &mut AnvilState| {
|
move |_, _, state: &mut AnvilState<Backend>| {
|
||||||
let mut display = display.borrow_mut();
|
let mut display = display.borrow_mut();
|
||||||
match display.dispatch(std::time::Duration::from_millis(0), state) {
|
match display.dispatch(std::time::Duration::from_millis(0), state) {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
|
@ -176,6 +174,7 @@ impl AnvilState {
|
||||||
};
|
};
|
||||||
|
|
||||||
AnvilState {
|
AnvilState {
|
||||||
|
backend: Default::default(),
|
||||||
running: Arc::new(AtomicBool::new(true)),
|
running: Arc::new(AtomicBool::new(true)),
|
||||||
display,
|
display,
|
||||||
handle,
|
handle,
|
||||||
|
|
|
@ -16,7 +16,7 @@ use slog::Logger;
|
||||||
use smithay::backend::{drm::DevPath, egl::display::EGLBufferReader, udev::primary_gpu};
|
use smithay::backend::{drm::DevPath, egl::display::EGLBufferReader, udev::primary_gpu};
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::{
|
backend::{
|
||||||
drm::{device_bind, DeviceHandler, DrmDevice, DrmError, DrmRenderSurface},
|
drm::{DrmDevice, DrmError, DrmEvent, DrmRenderSurface},
|
||||||
egl::{EGLContext, EGLDisplay},
|
egl::{EGLContext, EGLDisplay},
|
||||||
libinput::{LibinputInputBackend, LibinputSessionInterface},
|
libinput::{LibinputInputBackend, LibinputSessionInterface},
|
||||||
renderer::{
|
renderer::{
|
||||||
|
@ -29,9 +29,8 @@ use smithay::{
|
||||||
},
|
},
|
||||||
reexports::{
|
reexports::{
|
||||||
calloop::{
|
calloop::{
|
||||||
generic::Generic,
|
|
||||||
timer::{Timer, TimerHandle},
|
timer::{Timer, TimerHandle},
|
||||||
EventLoop, LoopHandle, Source,
|
Dispatcher, EventLoop, LoopHandle, RegistrationToken,
|
||||||
},
|
},
|
||||||
drm::{
|
drm::{
|
||||||
self,
|
self,
|
||||||
|
@ -71,9 +70,17 @@ impl AsRawFd for SessionFd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct UdevData {}
|
||||||
|
|
||||||
|
impl Default for UdevData {
|
||||||
|
fn default() -> UdevData {
|
||||||
|
UdevData {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn run_udev(
|
pub fn run_udev(
|
||||||
display: Rc<RefCell<Display>>,
|
display: Rc<RefCell<Display>>,
|
||||||
event_loop: &mut EventLoop<AnvilState>,
|
event_loop: &mut EventLoop<'static, AnvilState<UdevData>>,
|
||||||
log: Logger,
|
log: Logger,
|
||||||
) -> Result<(), ()> {
|
) -> Result<(), ()> {
|
||||||
let name = display
|
let name = display
|
||||||
|
@ -272,10 +279,11 @@ struct BackendData {
|
||||||
context: EGLContext,
|
context: EGLContext,
|
||||||
egl: EGLDisplay,
|
egl: EGLDisplay,
|
||||||
gbm: GbmDevice<SessionFd>,
|
gbm: GbmDevice<SessionFd>,
|
||||||
event_source: Source<Generic<DrmDevice<SessionFd>>>,
|
registration_token: RegistrationToken,
|
||||||
|
event_dispatcher: Dispatcher<'static, DrmDevice<SessionFd>, AnvilState<UdevData>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UdevHandlerImpl<Data: 'static> {
|
struct UdevHandlerImpl {
|
||||||
compositor_token: CompositorToken<Roles>,
|
compositor_token: CompositorToken<Roles>,
|
||||||
#[cfg(feature = "egl")]
|
#[cfg(feature = "egl")]
|
||||||
egl_buffer_reader: Rc<RefCell<Option<EGLBufferReader>>>,
|
egl_buffer_reader: Rc<RefCell<Option<EGLBufferReader>>>,
|
||||||
|
@ -290,12 +298,12 @@ struct UdevHandlerImpl<Data: 'static> {
|
||||||
pointer_image: ImageBuffer<Rgba<u8>, Vec<u8>>,
|
pointer_image: ImageBuffer<Rgba<u8>, Vec<u8>>,
|
||||||
cursor_status: Arc<Mutex<CursorImageStatus>>,
|
cursor_status: Arc<Mutex<CursorImageStatus>>,
|
||||||
dnd_icon: Arc<Mutex<Option<wl_surface::WlSurface>>>,
|
dnd_icon: Arc<Mutex<Option<wl_surface::WlSurface>>>,
|
||||||
loop_handle: LoopHandle<Data>,
|
loop_handle: LoopHandle<'static, AnvilState<UdevData>>,
|
||||||
signaler: Signaler<SessionSignal>,
|
signaler: Signaler<SessionSignal>,
|
||||||
logger: ::slog::Logger,
|
logger: ::slog::Logger,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Data: 'static> UdevHandlerImpl<Data> {
|
impl UdevHandlerImpl {
|
||||||
pub fn scan_connectors(
|
pub fn scan_connectors(
|
||||||
device: &mut DrmDevice<SessionFd>,
|
device: &mut DrmDevice<SessionFd>,
|
||||||
gbm: &GbmDevice<SessionFd>,
|
gbm: &GbmDevice<SessionFd>,
|
||||||
|
@ -392,7 +400,7 @@ impl<Data: 'static> UdevHandlerImpl<Data> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Data: 'static> UdevHandlerImpl<Data> {
|
impl UdevHandlerImpl {
|
||||||
fn device_added(&mut self, device_id: dev_t, path: PathBuf) {
|
fn device_added(&mut self, device_id: dev_t, path: PathBuf) {
|
||||||
// Try to open the device
|
// Try to open the device
|
||||||
if let Some((mut device, gbm)) = self
|
if let Some((mut device, gbm)) = self
|
||||||
|
@ -465,7 +473,7 @@ impl<Data: 'static> UdevHandlerImpl<Data> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let backends = Rc::new(RefCell::new(UdevHandlerImpl::<Data>::scan_connectors(
|
let backends = Rc::new(RefCell::new(UdevHandlerImpl::scan_connectors(
|
||||||
&mut device,
|
&mut device,
|
||||||
&gbm,
|
&gbm,
|
||||||
&egl,
|
&egl,
|
||||||
|
@ -516,15 +524,22 @@ impl<Data: 'static> UdevHandlerImpl<Data> {
|
||||||
SessionSignal::ActivateSession | SessionSignal::ActivateDevice { .. } => listener.activate(),
|
SessionSignal::ActivateSession | SessionSignal::ActivateDevice { .. } => listener.activate(),
|
||||||
_ => {}
|
_ => {}
|
||||||
});
|
});
|
||||||
device.set_handler(DrmHandlerImpl {
|
let mut drm_handler = DrmHandlerImpl {
|
||||||
renderer,
|
renderer,
|
||||||
loop_handle: self.loop_handle.clone(),
|
loop_handle: self.loop_handle.clone(),
|
||||||
});
|
};
|
||||||
|
|
||||||
device.link(self.signaler.clone());
|
device.link(self.signaler.clone());
|
||||||
let dev_id = device.device_id();
|
let dev_id = device.device_id();
|
||||||
let event_source = device_bind(&self.loop_handle, device)
|
let event_dispatcher = Dispatcher::new(device, move |event, _, _| match event {
|
||||||
.map_err(|e| -> IoError { e.into() })
|
DrmEvent::VBlank(crtc) => drm_handler.vblank(crtc),
|
||||||
|
DrmEvent::Error(error) => {
|
||||||
|
error!(drm_handler.renderer.logger, "{:?}", error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let registration_token = self
|
||||||
|
.loop_handle
|
||||||
|
.register_dispatcher(event_dispatcher.clone())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
trace!(self.logger, "Backends: {:?}", backends.borrow().keys());
|
trace!(self.logger, "Backends: {:?}", backends.borrow().keys());
|
||||||
|
@ -538,7 +553,8 @@ impl<Data: 'static> UdevHandlerImpl<Data> {
|
||||||
dev_id,
|
dev_id,
|
||||||
BackendData {
|
BackendData {
|
||||||
_restart_token: restart_token,
|
_restart_token: restart_token,
|
||||||
event_source,
|
registration_token,
|
||||||
|
event_dispatcher,
|
||||||
surfaces: backends,
|
surfaces: backends,
|
||||||
egl,
|
egl,
|
||||||
context,
|
context,
|
||||||
|
@ -557,11 +573,11 @@ impl<Data: 'static> UdevHandlerImpl<Data> {
|
||||||
let mut output_map = self.output_map.borrow_mut();
|
let mut output_map = self.output_map.borrow_mut();
|
||||||
let signaler = self.signaler.clone();
|
let signaler = self.signaler.clone();
|
||||||
output_map.retain(|output| output.device_id != device);
|
output_map.retain(|output| output.device_id != device);
|
||||||
self.loop_handle
|
|
||||||
.with_source(&backend_data.event_source, |source| {
|
let mut source = backend_data.event_dispatcher.as_source_mut();
|
||||||
let mut backends = backend_data.surfaces.borrow_mut();
|
let mut backends = backend_data.surfaces.borrow_mut();
|
||||||
*backends = UdevHandlerImpl::<Data>::scan_connectors(
|
*backends = UdevHandlerImpl::scan_connectors(
|
||||||
&mut source.file,
|
&mut *source,
|
||||||
&backend_data.gbm,
|
&backend_data.gbm,
|
||||||
&backend_data.egl,
|
&backend_data.egl,
|
||||||
&backend_data.context,
|
&backend_data.context,
|
||||||
|
@ -576,7 +592,6 @@ impl<Data: 'static> UdevHandlerImpl<Data> {
|
||||||
// render first frame
|
// render first frame
|
||||||
schedule_initial_render(renderer.clone(), &loop_handle, logger);
|
schedule_initial_render(renderer.clone(), &loop_handle, logger);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -591,7 +606,8 @@ impl<Data: 'static> UdevHandlerImpl<Data> {
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.retain(|output| output.device_id != device);
|
.retain(|output| output.device_id != device);
|
||||||
|
|
||||||
let _device = self.loop_handle.remove(backend_data.event_source).unwrap();
|
let _device = self.loop_handle.remove(backend_data.registration_token);
|
||||||
|
let _device = backend_data.event_dispatcher.into_source_inner();
|
||||||
|
|
||||||
// don't use hardware acceleration anymore, if this was the primary gpu
|
// don't use hardware acceleration anymore, if this was the primary gpu
|
||||||
#[cfg(feature = "egl")]
|
#[cfg(feature = "egl")]
|
||||||
|
@ -607,22 +623,18 @@ impl<Data: 'static> UdevHandlerImpl<Data> {
|
||||||
|
|
||||||
pub struct DrmHandlerImpl<Data: 'static> {
|
pub struct DrmHandlerImpl<Data: 'static> {
|
||||||
renderer: Rc<DrmRenderer>,
|
renderer: Rc<DrmRenderer>,
|
||||||
loop_handle: LoopHandle<Data>,
|
loop_handle: LoopHandle<'static, Data>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Data: 'static> DeviceHandler for DrmHandlerImpl<Data> {
|
impl<Data: 'static> DrmHandlerImpl<Data> {
|
||||||
fn vblank(&mut self, crtc: crtc::Handle) {
|
fn vblank(&mut self, crtc: crtc::Handle) {
|
||||||
self.renderer.clone().render(crtc, None, Some(&self.loop_handle))
|
self.renderer.clone().render(crtc, None, Some(&self.loop_handle))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error(&mut self, error: DrmError) {
|
|
||||||
error!(self.renderer.logger, "{:?}", error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DrmRendererSessionListener<Data: 'static> {
|
pub struct DrmRendererSessionListener<Data: 'static> {
|
||||||
renderer: Rc<DrmRenderer>,
|
renderer: Rc<DrmRenderer>,
|
||||||
loop_handle: LoopHandle<Data>,
|
loop_handle: LoopHandle<'static, Data>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Data: 'static> DrmRendererSessionListener<Data> {
|
impl<Data: 'static> DrmRendererSessionListener<Data> {
|
||||||
|
@ -652,7 +664,7 @@ pub struct DrmRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DrmRenderer {
|
impl DrmRenderer {
|
||||||
fn render_all<Data: 'static>(self: Rc<Self>, evt_handle: Option<&LoopHandle<Data>>) {
|
fn render_all<Data: 'static>(self: Rc<Self>, evt_handle: Option<&LoopHandle<'static, Data>>) {
|
||||||
for crtc in self.backends.borrow().keys() {
|
for crtc in self.backends.borrow().keys() {
|
||||||
self.clone().render(*crtc, None, evt_handle);
|
self.clone().render(*crtc, None, evt_handle);
|
||||||
}
|
}
|
||||||
|
@ -661,7 +673,7 @@ impl DrmRenderer {
|
||||||
self: Rc<Self>,
|
self: Rc<Self>,
|
||||||
crtc: crtc::Handle,
|
crtc: crtc::Handle,
|
||||||
timer: Option<TimerHandle<(std::rc::Weak<DrmRenderer>, crtc::Handle)>>,
|
timer: Option<TimerHandle<(std::rc::Weak<DrmRenderer>, crtc::Handle)>>,
|
||||||
evt_handle: Option<&LoopHandle<Data>>,
|
evt_handle: Option<&LoopHandle<'static, Data>>,
|
||||||
) {
|
) {
|
||||||
if let Some(surface) = self.backends.borrow().get(&crtc) {
|
if let Some(surface) = self.backends.borrow().get(&crtc) {
|
||||||
let result = DrmRenderer::render_surface(
|
let result = DrmRenderer::render_surface(
|
||||||
|
@ -716,7 +728,7 @@ impl DrmRenderer {
|
||||||
renderer.render(
|
renderer.render(
|
||||||
crtc,
|
crtc,
|
||||||
Some(handle.clone()),
|
Some(handle.clone()),
|
||||||
Option::<&LoopHandle<Data>>::None,
|
Option::<&LoopHandle<'static, Data>>::None,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -846,7 +858,7 @@ impl DrmRenderer {
|
||||||
|
|
||||||
fn schedule_initial_render<Data: 'static>(
|
fn schedule_initial_render<Data: 'static>(
|
||||||
renderer: Rc<RefCell<RenderSurface>>,
|
renderer: Rc<RefCell<RenderSurface>>,
|
||||||
evt_handle: &LoopHandle<Data>,
|
evt_handle: &LoopHandle<'static, Data>,
|
||||||
logger: ::slog::Logger,
|
logger: ::slog::Logger,
|
||||||
) {
|
) {
|
||||||
let result = {
|
let result = {
|
||||||
|
|
|
@ -17,9 +17,17 @@ use slog::Logger;
|
||||||
use crate::drawing::*;
|
use crate::drawing::*;
|
||||||
use crate::state::AnvilState;
|
use crate::state::AnvilState;
|
||||||
|
|
||||||
|
pub struct WinitData;
|
||||||
|
|
||||||
|
impl Default for WinitData {
|
||||||
|
fn default() -> WinitData {
|
||||||
|
WinitData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn run_winit(
|
pub fn run_winit(
|
||||||
display: Rc<RefCell<Display>>,
|
display: Rc<RefCell<Display>>,
|
||||||
event_loop: &mut EventLoop<AnvilState>,
|
event_loop: &mut EventLoop<'static, AnvilState<WinitData>>,
|
||||||
log: Logger,
|
log: Logger,
|
||||||
) -> Result<(), ()> {
|
) -> Result<(), ()> {
|
||||||
let (renderer, mut input) = winit::init(log.clone()).map_err(|err| {
|
let (renderer, mut input) = winit::init(log.clone()).map_err(|err| {
|
||||||
|
|
|
@ -35,16 +35,16 @@ mod x11rb_event_source;
|
||||||
|
|
||||||
/// Implementation of [`smithay::xwayland::XWindowManager`] that is used for starting XWayland.
|
/// Implementation of [`smithay::xwayland::XWindowManager`] that is used for starting XWayland.
|
||||||
/// After XWayland was started, the actual state is kept in `X11State`.
|
/// After XWayland was started, the actual state is kept in `X11State`.
|
||||||
pub struct XWm {
|
pub struct XWm<Backend> {
|
||||||
handle: LoopHandle<AnvilState>,
|
handle: LoopHandle<'static, AnvilState<Backend>>,
|
||||||
token: CompositorToken<Roles>,
|
token: CompositorToken<Roles>,
|
||||||
window_map: Rc<RefCell<MyWindowMap>>,
|
window_map: Rc<RefCell<MyWindowMap>>,
|
||||||
log: slog::Logger,
|
log: slog::Logger,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XWm {
|
impl<Backend> XWm<Backend> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
handle: LoopHandle<AnvilState>,
|
handle: LoopHandle<'static, AnvilState<Backend>>,
|
||||||
token: CompositorToken<Roles>,
|
token: CompositorToken<Roles>,
|
||||||
window_map: Rc<RefCell<MyWindowMap>>,
|
window_map: Rc<RefCell<MyWindowMap>>,
|
||||||
log: slog::Logger,
|
log: slog::Logger,
|
||||||
|
@ -58,7 +58,7 @@ impl XWm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XWindowManager for XWm {
|
impl<Backend> XWindowManager for XWm<Backend> {
|
||||||
fn xwayland_ready(&mut self, connection: UnixStream, client: Client) {
|
fn xwayland_ready(&mut self, connection: UnixStream, client: Client) {
|
||||||
let (wm, source) =
|
let (wm, source) =
|
||||||
X11State::start_wm(connection, self.token, self.window_map.clone(), self.log.clone()).unwrap();
|
X11State::start_wm(connection, self.token, self.window_map.clone(), self.log.clone()).unwrap();
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub struct X11Source {
|
||||||
impl X11Source {
|
impl X11Source {
|
||||||
pub fn new(connection: Rc<RustConnection>) -> Self {
|
pub fn new(connection: Rc<RustConnection>) -> Self {
|
||||||
let fd = Fd(connection.stream().as_raw_fd());
|
let fd = Fd(connection.stream().as_raw_fd());
|
||||||
let generic = Generic::new(fd, Interest::Readable, Mode::Level);
|
let generic = Generic::new(fd, Interest::READ, Mode::Level);
|
||||||
Self { connection, generic }
|
Self { connection, generic }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use slog::Drain;
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::{
|
backend::{
|
||||||
allocator::{dumb::DumbBuffer, Fourcc, Slot, Swapchain},
|
allocator::{dumb::DumbBuffer, Fourcc, Slot, Swapchain},
|
||||||
drm::{device_bind, DeviceHandler, DrmDevice, DrmError, DrmSurface},
|
drm::{DrmDevice, DrmEvent, DrmSurface},
|
||||||
},
|
},
|
||||||
reexports::{
|
reexports::{
|
||||||
calloop::EventLoop,
|
calloop::EventLoop,
|
||||||
|
@ -16,7 +16,6 @@ use smithay::{
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
fs::{File, OpenOptions},
|
fs::{File, OpenOptions},
|
||||||
io::Error as IoError,
|
|
||||||
os::unix::io::{AsRawFd, RawFd},
|
os::unix::io::{AsRawFd, RawFd},
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
sync::Mutex,
|
sync::Mutex,
|
||||||
|
@ -48,7 +47,7 @@ fn main() {
|
||||||
file: Rc::new(options.open("/dev/dri/card0").unwrap()),
|
file: Rc::new(options.open("/dev/dri/card0").unwrap()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut device = DrmDevice::new(fd.clone(), true, log.clone()).unwrap();
|
let device = DrmDevice::new(fd.clone(), true, log.clone()).unwrap();
|
||||||
|
|
||||||
// Get a set of all modesetting resource handles (excluding planes):
|
// Get a set of all modesetting resource handles (excluding planes):
|
||||||
let res_handles = ControlDevice::resource_handles(&device).unwrap();
|
let res_handles = ControlDevice::resource_handles(&device).unwrap();
|
||||||
|
@ -111,20 +110,23 @@ fn main() {
|
||||||
*first_buffer.userdata() = Some(framebuffer);
|
*first_buffer.userdata() = Some(framebuffer);
|
||||||
|
|
||||||
// Get the device as an allocator into the
|
// Get the device as an allocator into the
|
||||||
device.set_handler(DrmHandlerImpl {
|
let mut vblank_handler = VBlankHandler {
|
||||||
swapchain,
|
swapchain,
|
||||||
current: first_buffer,
|
current: first_buffer,
|
||||||
surface: surface.clone(),
|
surface: surface.clone(),
|
||||||
});
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register the DrmDevice on the EventLoop
|
* Register the DrmDevice on the EventLoop
|
||||||
*/
|
*/
|
||||||
let mut event_loop = EventLoop::<()>::new().unwrap();
|
let mut event_loop = EventLoop::<()>::try_new().unwrap();
|
||||||
let _source = device_bind(&event_loop.handle(), device)
|
event_loop
|
||||||
.map_err(|err| -> IoError { err.into() })
|
.handle()
|
||||||
|
.insert_source(device, move |event, _: &mut (), _: &mut ()| match event {
|
||||||
|
DrmEvent::VBlank(crtc) => vblank_handler.vblank(crtc),
|
||||||
|
DrmEvent::Error(e) => panic!("{}", e),
|
||||||
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Start rendering
|
// Start rendering
|
||||||
surface
|
surface
|
||||||
.commit([(framebuffer, surface.plane())].iter(), true)
|
.commit([(framebuffer, surface.plane())].iter(), true)
|
||||||
|
@ -134,13 +136,13 @@ fn main() {
|
||||||
event_loop.run(None, &mut (), |_| {}).unwrap();
|
event_loop.run(None, &mut (), |_| {}).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DrmHandlerImpl {
|
pub struct VBlankHandler {
|
||||||
swapchain: Swapchain<DrmDevice<FdWrapper>, DumbBuffer<FdWrapper>, framebuffer::Handle>,
|
swapchain: Swapchain<DrmDevice<FdWrapper>, DumbBuffer<FdWrapper>, framebuffer::Handle>,
|
||||||
current: Slot<DumbBuffer<FdWrapper>, framebuffer::Handle>,
|
current: Slot<DumbBuffer<FdWrapper>, framebuffer::Handle>,
|
||||||
surface: Rc<DrmSurface<FdWrapper>>,
|
surface: Rc<DrmSurface<FdWrapper>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeviceHandler for DrmHandlerImpl {
|
impl VBlankHandler {
|
||||||
fn vblank(&mut self, _crtc: crtc::Handle) {
|
fn vblank(&mut self, _crtc: crtc::Handle) {
|
||||||
{
|
{
|
||||||
// Next buffer
|
// Next buffer
|
||||||
|
@ -168,8 +170,4 @@ impl DeviceHandler for DrmHandlerImpl {
|
||||||
.page_flip([(fb, self.surface.plane())].iter(), true)
|
.page_flip([(fb, self.surface.plane())].iter(), true)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error(&mut self, error: DrmError) {
|
|
||||||
panic!("{:?}", error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::os::unix::io::{AsRawFd, RawFd};
|
use std::os::unix::io::{AsRawFd, RawFd};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::rc::Rc;
|
|
||||||
use std::sync::{atomic::AtomicBool, Arc};
|
use std::sync::{atomic::AtomicBool, Arc};
|
||||||
|
|
||||||
use calloop::{generic::Generic, InsertError, LoopHandle, Source};
|
use calloop::{EventSource, Interest, Poll, Readiness, Token};
|
||||||
use drm::control::{connector, crtc, Device as ControlDevice, Event, Mode, ResourceHandles};
|
use drm::control::{connector, crtc, Device as ControlDevice, Event, Mode, ResourceHandles};
|
||||||
use drm::{ClientCapability, Device as BasicDevice};
|
use drm::{ClientCapability, Device as BasicDevice};
|
||||||
use nix::libc::dev_t;
|
use nix::libc::dev_t;
|
||||||
|
@ -21,7 +20,6 @@ use legacy::LegacyDrmDevice;
|
||||||
pub struct DrmDevice<A: AsRawFd + 'static> {
|
pub struct DrmDevice<A: AsRawFd + 'static> {
|
||||||
pub(super) dev_id: dev_t,
|
pub(super) dev_id: dev_t,
|
||||||
pub(crate) internal: Arc<DrmDeviceInternal<A>>,
|
pub(crate) internal: Arc<DrmDeviceInternal<A>>,
|
||||||
handler: Rc<RefCell<Option<Box<dyn DeviceHandler>>>>,
|
|
||||||
#[cfg(feature = "backend_session")]
|
#[cfg(feature = "backend_session")]
|
||||||
pub(super) links: RefCell<Vec<crate::signaling::SignalToken>>,
|
pub(super) links: RefCell<Vec<crate::signaling::SignalToken>>,
|
||||||
has_universal_planes: bool,
|
has_universal_planes: bool,
|
||||||
|
@ -145,7 +143,6 @@ impl<A: AsRawFd + 'static> DrmDevice<A> {
|
||||||
Ok(DrmDevice {
|
Ok(DrmDevice {
|
||||||
dev_id,
|
dev_id,
|
||||||
internal,
|
internal,
|
||||||
handler: Rc::new(RefCell::new(None)),
|
|
||||||
#[cfg(feature = "backend_session")]
|
#[cfg(feature = "backend_session")]
|
||||||
links: RefCell::new(Vec::new()),
|
links: RefCell::new(Vec::new()),
|
||||||
has_universal_planes,
|
has_universal_planes,
|
||||||
|
@ -180,43 +177,6 @@ impl<A: AsRawFd + 'static> DrmDevice<A> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Processes any open events of the underlying file descriptor.
|
|
||||||
///
|
|
||||||
/// You should not call this function manually, but rather use
|
|
||||||
/// [`device_bind`] to register the device
|
|
||||||
/// to an [`EventLoop`](calloop::EventLoop)
|
|
||||||
/// and call this function when the device becomes readable
|
|
||||||
/// to synchronize your rendering to the vblank events of the open crtc's
|
|
||||||
pub fn process_events(&mut self) {
|
|
||||||
match self.receive_events() {
|
|
||||||
Ok(events) => {
|
|
||||||
for event in events {
|
|
||||||
if let Event::PageFlip(event) = event {
|
|
||||||
trace!(self.logger, "Got a page-flip event for crtc ({:?})", event.crtc);
|
|
||||||
if let Some(handler) = self.handler.borrow_mut().as_mut() {
|
|
||||||
handler.vblank(event.crtc);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
trace!(
|
|
||||||
self.logger,
|
|
||||||
"Got a non-page-flip event of device '{:?}'.",
|
|
||||||
self.dev_path()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(source) => {
|
|
||||||
if let Some(handler) = self.handler.borrow_mut().as_mut() {
|
|
||||||
handler.error(Error::Access {
|
|
||||||
errmsg: "Error processing drm events",
|
|
||||||
dev: self.dev_path(),
|
|
||||||
source,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns if the underlying implementation uses atomic-modesetting or not.
|
/// Returns if the underlying implementation uses atomic-modesetting or not.
|
||||||
pub fn is_atomic(&self) -> bool {
|
pub fn is_atomic(&self) -> bool {
|
||||||
match *self.internal {
|
match *self.internal {
|
||||||
|
@ -225,19 +185,6 @@ impl<A: AsRawFd + 'static> DrmDevice<A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Assigns a [`DeviceHandler`] called during event processing.
|
|
||||||
///
|
|
||||||
/// See [`device_bind`] and [`DeviceHandler`]
|
|
||||||
pub fn set_handler(&mut self, handler: impl DeviceHandler + 'static) {
|
|
||||||
let handler = Some(Box::new(handler) as Box<dyn DeviceHandler + 'static>);
|
|
||||||
*self.handler.borrow_mut() = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Clear a set [`DeviceHandler`](trait.DeviceHandler.html), if any
|
|
||||||
pub fn clear_handler(&mut self) {
|
|
||||||
self.handler.borrow_mut().take();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a list of crtcs for this device
|
/// Returns a list of crtcs for this device
|
||||||
pub fn crtcs(&self) -> &[crtc::Handle] {
|
pub fn crtcs(&self) -> &[crtc::Handle] {
|
||||||
self.resources.crtcs()
|
self.resources.crtcs()
|
||||||
|
@ -334,16 +281,6 @@ impl<A: AsRawFd + 'static> DrmDevice<A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait to receive events of a bound [`DrmDevice`]
|
|
||||||
///
|
|
||||||
/// See [`device_bind`]
|
|
||||||
pub trait DeviceHandler {
|
|
||||||
/// A vblank blank event on the provided crtc has happend
|
|
||||||
fn vblank(&mut self, crtc: crtc::Handle);
|
|
||||||
/// An error happend while processing events
|
|
||||||
fn error(&mut self, error: Error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Trait representing open devices that *may* return a `Path`
|
/// Trait representing open devices that *may* return a `Path`
|
||||||
pub trait DevPath {
|
pub trait DevPath {
|
||||||
/// Returns the path of the open device if possible
|
/// Returns the path of the open device if possible
|
||||||
|
@ -358,25 +295,64 @@ impl<A: AsRawFd> DevPath for A {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// calloop source associated with a Device
|
/// Events that can be generated by a DrmDevice
|
||||||
pub type DrmSource<A> = Generic<DrmDevice<A>>;
|
pub enum DrmEvent {
|
||||||
|
/// A vblank blank event on the provided crtc has happend
|
||||||
|
VBlank(crtc::Handle),
|
||||||
|
/// An error happend while processing events
|
||||||
|
Error(Error),
|
||||||
|
}
|
||||||
|
|
||||||
/// Bind a `Device` to an [`EventLoop`](calloop::EventLoop),
|
impl<A> EventSource for DrmDevice<A>
|
||||||
///
|
|
||||||
/// This will cause it to recieve events and feed them into a previously
|
|
||||||
/// set [`DeviceHandler`](DeviceHandler).
|
|
||||||
pub fn device_bind<A, Data>(
|
|
||||||
handle: &LoopHandle<Data>,
|
|
||||||
device: DrmDevice<A>,
|
|
||||||
) -> ::std::result::Result<Source<DrmSource<A>>, InsertError<DrmSource<A>>>
|
|
||||||
where
|
where
|
||||||
A: AsRawFd + 'static,
|
A: AsRawFd + 'static,
|
||||||
Data: 'static,
|
|
||||||
{
|
{
|
||||||
let source = Generic::new(device, calloop::Interest::Readable, calloop::Mode::Level);
|
type Event = DrmEvent;
|
||||||
|
type Metadata = ();
|
||||||
|
type Ret = ();
|
||||||
|
|
||||||
handle.insert_source(source, |_, source, _| {
|
fn process_events<F>(&mut self, _: Readiness, _: Token, mut callback: F) -> std::io::Result<()>
|
||||||
source.process_events();
|
where
|
||||||
|
F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
|
||||||
|
{
|
||||||
|
match self.receive_events() {
|
||||||
|
Ok(events) => {
|
||||||
|
for event in events {
|
||||||
|
if let Event::PageFlip(event) = event {
|
||||||
|
trace!(self.logger, "Got a page-flip event for crtc ({:?})", event.crtc);
|
||||||
|
callback(DrmEvent::VBlank(event.crtc), &mut ());
|
||||||
|
} else {
|
||||||
|
trace!(
|
||||||
|
self.logger,
|
||||||
|
"Got a non-page-flip event of device '{:?}'.",
|
||||||
|
self.dev_path()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(source) => {
|
||||||
|
callback(
|
||||||
|
DrmEvent::Error(Error::Access {
|
||||||
|
errmsg: "Error processing drm events",
|
||||||
|
dev: self.dev_path(),
|
||||||
|
source,
|
||||||
|
}),
|
||||||
|
&mut (),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
}
|
||||||
|
|
||||||
|
fn register(&mut self, poll: &mut Poll, token: Token) -> std::io::Result<()> {
|
||||||
|
poll.register(self.as_raw_fd(), Interest::READ, calloop::Mode::Level, token)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reregister(&mut self, poll: &mut Poll, token: Token) -> std::io::Result<()> {
|
||||||
|
poll.reregister(self.as_raw_fd(), Interest::READ, calloop::Mode::Level, token)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unregister(&mut self, poll: &mut Poll) -> std::io::Result<()> {
|
||||||
|
poll.unregister(self.as_raw_fd())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ mod render;
|
||||||
pub(self) mod session;
|
pub(self) mod session;
|
||||||
pub(self) mod surface;
|
pub(self) mod surface;
|
||||||
|
|
||||||
pub use device::{device_bind, DevPath, DeviceHandler, DrmDevice, DrmSource};
|
pub use device::{DevPath, DrmDevice, DrmEvent};
|
||||||
pub use error::Error as DrmError;
|
pub use error::Error as DrmError;
|
||||||
#[cfg(feature = "backend_gbm")]
|
#[cfg(feature = "backend_gbm")]
|
||||||
pub use render::{DrmRenderSurface, Error as DrmRenderError};
|
pub use render::{DrmRenderSurface, Error as DrmRenderError};
|
||||||
|
|
|
@ -469,11 +469,11 @@ impl EventSource for LibinputInputBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register(&mut self, poll: &mut Poll, token: Token) -> std::io::Result<()> {
|
fn register(&mut self, poll: &mut Poll, token: Token) -> std::io::Result<()> {
|
||||||
poll.register(self.as_raw_fd(), Interest::Readable, Mode::Level, token)
|
poll.register(self.as_raw_fd(), Interest::READ, Mode::Level, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reregister(&mut self, poll: &mut Poll, token: Token) -> std::io::Result<()> {
|
fn reregister(&mut self, poll: &mut Poll, token: Token) -> std::io::Result<()> {
|
||||||
poll.reregister(self.as_raw_fd(), Interest::Readable, Mode::Level, token)
|
poll.reregister(self.as_raw_fd(), Interest::READ, Mode::Level, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unregister(&mut self, poll: &mut Poll) -> std::io::Result<()> {
|
fn unregister(&mut self, poll: &mut Poll) -> std::io::Result<()> {
|
||||||
|
|
|
@ -76,9 +76,9 @@ impl EventSource for DBusConnection {
|
||||||
fn reregister(&mut self, poll: &mut Poll, token: Token) -> io::Result<()> {
|
fn reregister(&mut self, poll: &mut Poll, token: Token) -> io::Result<()> {
|
||||||
let new_watch = self.cx.channel().watch();
|
let new_watch = self.cx.channel().watch();
|
||||||
let new_interest = match (new_watch.read, new_watch.write) {
|
let new_interest = match (new_watch.read, new_watch.write) {
|
||||||
(true, true) => Some(Interest::Both),
|
(true, true) => Some(Interest::BOTH),
|
||||||
(true, false) => Some(Interest::Readable),
|
(true, false) => Some(Interest::READ),
|
||||||
(false, true) => Some(Interest::Writable),
|
(false, true) => Some(Interest::WRITE),
|
||||||
(false, false) => None,
|
(false, false) => None,
|
||||||
};
|
};
|
||||||
if new_watch.fd != self.current_watch.fd {
|
if new_watch.fd != self.current_watch.fd {
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
//! // process the initial list of devices
|
//! // process the initial list of devices
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! # let event_loop = smithay::reexports::calloop::EventLoop::<()>::new().unwrap();
|
//! # let event_loop = smithay::reexports::calloop::EventLoop::<()>::try_new().unwrap();
|
||||||
//! # let loop_handle = event_loop.handle();
|
//! # let loop_handle = event_loop.handle();
|
||||||
//! // setup the event source for long-term monitoring
|
//! // setup the event source for long-term monitoring
|
||||||
//! loop_handle.insert_source(udev, |event, _, _dispatch_data| match event {
|
//! loop_handle.insert_source(udev, |event, _, _dispatch_data| match event {
|
||||||
|
@ -182,11 +182,11 @@ impl EventSource for UdevBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register(&mut self, poll: &mut Poll, token: Token) -> std::io::Result<()> {
|
fn register(&mut self, poll: &mut Poll, token: Token) -> std::io::Result<()> {
|
||||||
poll.register(self.as_raw_fd(), Interest::Readable, Mode::Level, token)
|
poll.register(self.as_raw_fd(), Interest::READ, Mode::Level, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reregister(&mut self, poll: &mut Poll, token: Token) -> std::io::Result<()> {
|
fn reregister(&mut self, poll: &mut Poll, token: Token) -> std::io::Result<()> {
|
||||||
poll.reregister(self.as_raw_fd(), Interest::Readable, Mode::Level, token)
|
poll.reregister(self.as_raw_fd(), Interest::READ, Mode::Level, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unregister(&mut self, poll: &mut Poll) -> std::io::Result<()> {
|
fn unregister(&mut self, poll: &mut Poll) -> std::io::Result<()> {
|
||||||
|
|
|
@ -55,7 +55,7 @@ use std::{
|
||||||
|
|
||||||
use calloop::{
|
use calloop::{
|
||||||
generic::{Fd, Generic},
|
generic::{Fd, Generic},
|
||||||
Interest, LoopHandle, Mode, Source,
|
Interest, LoopHandle, Mode, RegistrationToken,
|
||||||
};
|
};
|
||||||
|
|
||||||
use nix::Error as NixError;
|
use nix::Error as NixError;
|
||||||
|
@ -91,7 +91,7 @@ impl<WM: XWindowManager + 'static> XWayland<WM> {
|
||||||
/// Start the XWayland server
|
/// Start the XWayland server
|
||||||
pub fn init<L, T: Any, Data: 'static>(
|
pub fn init<L, T: Any, Data: 'static>(
|
||||||
wm: WM,
|
wm: WM,
|
||||||
handle: LoopHandle<Data>,
|
handle: LoopHandle<'static, Data>,
|
||||||
display: Rc<RefCell<Display>>,
|
display: Rc<RefCell<Display>>,
|
||||||
data: &mut T,
|
data: &mut T,
|
||||||
logger: L,
|
logger: L,
|
||||||
|
@ -109,7 +109,7 @@ impl<WM: XWindowManager + 'static> XWayland<WM> {
|
||||||
source_maker: Box::new(move |inner, fd| {
|
source_maker: Box::new(move |inner, fd| {
|
||||||
handle
|
handle
|
||||||
.insert_source(
|
.insert_source(
|
||||||
Generic::new(Fd(fd), Interest::Readable, Mode::Level),
|
Generic::new(Fd(fd), Interest::READ, Mode::Level),
|
||||||
move |evt, _, _| {
|
move |evt, _, _| {
|
||||||
debug_assert!(evt.readable);
|
debug_assert!(evt.readable);
|
||||||
xwayland_ready(&inner);
|
xwayland_ready(&inner);
|
||||||
|
@ -136,13 +136,13 @@ impl<WM: XWindowManager> Drop for XWayland<WM> {
|
||||||
struct XWaylandInstance {
|
struct XWaylandInstance {
|
||||||
display_lock: X11Lock,
|
display_lock: X11Lock,
|
||||||
wayland_client: Client,
|
wayland_client: Client,
|
||||||
startup_handler: Option<Source<Generic<Fd>>>,
|
startup_handler: Option<RegistrationToken>,
|
||||||
wm_fd: Option<UnixStream>,
|
wm_fd: Option<UnixStream>,
|
||||||
started_at: ::std::time::Instant,
|
started_at: ::std::time::Instant,
|
||||||
child_stdout: Option<ChildStdout>,
|
child_stdout: Option<ChildStdout>,
|
||||||
}
|
}
|
||||||
|
|
||||||
type SourceMaker<WM> = dyn FnMut(Rc<RefCell<Inner<WM>>>, RawFd) -> Result<Source<Generic<Fd>>, ()>;
|
type SourceMaker<WM> = dyn FnMut(Rc<RefCell<Inner<WM>>>, RawFd) -> Result<RegistrationToken, ()>;
|
||||||
|
|
||||||
// Inner implementation of the XWayland manager
|
// Inner implementation of the XWayland manager
|
||||||
struct Inner<WM: XWindowManager> {
|
struct Inner<WM: XWindowManager> {
|
||||||
|
@ -150,7 +150,7 @@ struct Inner<WM: XWindowManager> {
|
||||||
source_maker: Box<SourceMaker<WM>>,
|
source_maker: Box<SourceMaker<WM>>,
|
||||||
wayland_display: Rc<RefCell<Display>>,
|
wayland_display: Rc<RefCell<Display>>,
|
||||||
instance: Option<XWaylandInstance>,
|
instance: Option<XWaylandInstance>,
|
||||||
kill_source: Box<dyn Fn(Source<Generic<Fd>>)>,
|
kill_source: Box<dyn Fn(RegistrationToken)>,
|
||||||
log: ::slog::Logger,
|
log: ::slog::Logger,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue