backend: add DevicesEnumerated event
This commit is contained in:
parent
dddd68ba06
commit
c6c87bdaa1
11 changed files with 65 additions and 4 deletions
|
|
@ -42,6 +42,7 @@ pub(crate) struct Client {
|
||||||
on_new_input_device: RefCell<Option<Rc<dyn Fn(InputDevice)>>>,
|
on_new_input_device: RefCell<Option<Rc<dyn Fn(InputDevice)>>>,
|
||||||
on_connector_connected: RefCell<Option<Rc<dyn Fn(Connector)>>>,
|
on_connector_connected: RefCell<Option<Rc<dyn Fn(Connector)>>>,
|
||||||
on_graphics_initialized: Cell<Option<Box<dyn FnOnce()>>>,
|
on_graphics_initialized: Cell<Option<Box<dyn FnOnce()>>>,
|
||||||
|
on_devices_enumerated: Cell<Option<Box<dyn FnOnce()>>>,
|
||||||
on_new_connector: RefCell<Option<Rc<dyn Fn(Connector)>>>,
|
on_new_connector: RefCell<Option<Rc<dyn Fn(Connector)>>>,
|
||||||
on_new_drm_device: RefCell<Option<Rc<dyn Fn(DrmDevice)>>>,
|
on_new_drm_device: RefCell<Option<Rc<dyn Fn(DrmDevice)>>>,
|
||||||
on_del_drm_device: RefCell<Option<Rc<dyn Fn(DrmDevice)>>>,
|
on_del_drm_device: RefCell<Option<Rc<dyn Fn(DrmDevice)>>>,
|
||||||
|
|
@ -129,6 +130,7 @@ pub unsafe extern "C" fn init(
|
||||||
on_new_input_device: Default::default(),
|
on_new_input_device: Default::default(),
|
||||||
on_connector_connected: Default::default(),
|
on_connector_connected: Default::default(),
|
||||||
on_graphics_initialized: Default::default(),
|
on_graphics_initialized: Default::default(),
|
||||||
|
on_devices_enumerated: Default::default(),
|
||||||
on_new_connector: Default::default(),
|
on_new_connector: Default::default(),
|
||||||
on_new_drm_device: Default::default(),
|
on_new_drm_device: Default::default(),
|
||||||
on_del_drm_device: Default::default(),
|
on_del_drm_device: Default::default(),
|
||||||
|
|
@ -550,6 +552,10 @@ impl Client {
|
||||||
self.on_graphics_initialized.set(Some(Box::new(f)));
|
self.on_graphics_initialized.set(Some(Box::new(f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn on_devices_enumerated<F: FnOnce() + 'static>(&self, f: F) {
|
||||||
|
self.on_devices_enumerated.set(Some(Box::new(f)));
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_seat(&self, device: InputDevice, seat: Seat) {
|
pub fn set_seat(&self, device: InputDevice, seat: Seat) {
|
||||||
self.send(&ClientMessage::SetSeat { device, seat })
|
self.send(&ClientMessage::SetSeat { device, seat })
|
||||||
}
|
}
|
||||||
|
|
@ -734,6 +740,11 @@ impl Client {
|
||||||
handler();
|
handler();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ServerMessage::DevicesEnumerated => {
|
||||||
|
if let Some(handler) = self.on_devices_enumerated.take() {
|
||||||
|
handler();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ pub enum ServerMessage {
|
||||||
device: DrmDevice,
|
device: DrmDevice,
|
||||||
},
|
},
|
||||||
Idle,
|
Idle,
|
||||||
|
DevicesEnumerated,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Encode, BorrowDecode, Debug)]
|
#[derive(Encode, BorrowDecode, Debug)]
|
||||||
|
|
|
||||||
|
|
@ -139,3 +139,11 @@ impl Display for PciId {
|
||||||
pub fn on_idle<F: Fn() + 'static>(f: F) {
|
pub fn on_idle<F: Fn() + 'static>(f: F) {
|
||||||
get!().on_idle(f)
|
get!().on_idle(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the callback to be called when all devices have been enumerated.
|
||||||
|
///
|
||||||
|
/// This callback is only invoked once during the lifetime of the compositor. This is a
|
||||||
|
/// good place to select the DRM device used for rendering.
|
||||||
|
pub fn on_devices_enumerated<F: FnOnce() + 'static>(f: F) {
|
||||||
|
get!().on_devices_enumerated(f)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,7 @@ pub enum BackendEvent {
|
||||||
NewDrmDevice(Rc<dyn BackendDrmDevice>),
|
NewDrmDevice(Rc<dyn BackendDrmDevice>),
|
||||||
NewConnector(Rc<dyn Connector>),
|
NewConnector(Rc<dyn Connector>),
|
||||||
NewInputDevice(Rc<dyn InputDevice>),
|
NewInputDevice(Rc<dyn InputDevice>),
|
||||||
|
DevicesEnumerated,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ use {
|
||||||
clonecell::{CloneCell, UnsafeCellCloneSafe},
|
clonecell::{CloneCell, UnsafeCellCloneSafe},
|
||||||
copyhashmap::CopyHashMap,
|
copyhashmap::CopyHashMap,
|
||||||
errorfmt::ErrorFmt,
|
errorfmt::ErrorFmt,
|
||||||
|
numcell::NumCell,
|
||||||
oserror::OsError,
|
oserror::OsError,
|
||||||
smallmap::SmallMap,
|
smallmap::SmallMap,
|
||||||
syncqueue::SyncQueue,
|
syncqueue::SyncQueue,
|
||||||
|
|
@ -226,6 +227,7 @@ pub async fn create(state: &Rc<State>) -> Result<Rc<MetalBackend>, MetalError> {
|
||||||
input_devices: Default::default(),
|
input_devices: Default::default(),
|
||||||
drm_devices: Default::default(),
|
drm_devices: Default::default(),
|
||||||
pending_drm_devices: Default::default(),
|
pending_drm_devices: Default::default(),
|
||||||
|
num_pending_devices: Default::default(),
|
||||||
});
|
});
|
||||||
let udev = Rc::new(Udev::new()?);
|
let udev = Rc::new(Udev::new()?);
|
||||||
let monitor = Rc::new(udev.create_monitor()?);
|
let monitor = Rc::new(udev.create_monitor()?);
|
||||||
|
|
@ -309,6 +311,7 @@ struct DeviceHolder {
|
||||||
input_devices: RefCell<Vec<Option<Rc<MetalInputDevice>>>>,
|
input_devices: RefCell<Vec<Option<Rc<MetalInputDevice>>>>,
|
||||||
drm_devices: CopyHashMap<c::dev_t, Rc<MetalDrmDeviceData>>,
|
drm_devices: CopyHashMap<c::dev_t, Rc<MetalDrmDeviceData>>,
|
||||||
pending_drm_devices: CopyHashMap<c::dev_t, PendingDrmDevice>,
|
pending_drm_devices: CopyHashMap<c::dev_t, PendingDrmDevice>,
|
||||||
|
num_pending_devices: NumCell<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LibInputAdapter for DeviceHolder {
|
impl LibInputAdapter for DeviceHolder {
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,13 @@ use {
|
||||||
video::{MetalDrmDeviceData, PendingDrmDevice},
|
video::{MetalDrmDeviceData, PendingDrmDevice},
|
||||||
MetalBackend, MetalDevice, MetalError, MetalInputDevice,
|
MetalBackend, MetalDevice, MetalError, MetalInputDevice,
|
||||||
},
|
},
|
||||||
dbus::TRUE,
|
dbus::{DbusError, TRUE},
|
||||||
udev::UdevDevice,
|
udev::UdevDevice,
|
||||||
utils::{bitflags::BitflagsExt, errorfmt::ErrorFmt, nonblock::set_nonblock},
|
utils::{bitflags::BitflagsExt, errorfmt::ErrorFmt, nonblock::set_nonblock},
|
||||||
video::drm::DrmMaster,
|
video::drm::DrmMaster,
|
||||||
wire_dbus::org::freedesktop::login1::session::{PauseDevice, ResumeDevice},
|
wire_dbus::org::freedesktop::login1::session::{
|
||||||
|
PauseDevice, ResumeDevice, TakeDeviceReply,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
bstr::ByteSlice,
|
bstr::ByteSlice,
|
||||||
std::{cell::Cell, rc::Rc},
|
std::{cell::Cell, rc::Rc},
|
||||||
|
|
@ -199,7 +201,7 @@ impl MetalBackend {
|
||||||
};
|
};
|
||||||
self.device_holder.pending_drm_devices.set(devnum, dev);
|
self.device_holder.pending_drm_devices.set(devnum, dev);
|
||||||
let slf = self.clone();
|
let slf = self.clone();
|
||||||
self.session.get_device(devnum, move |res| {
|
self.get_device(devnum, move |res| {
|
||||||
let dev = match slf.device_holder.pending_drm_devices.remove(&devnum) {
|
let dev = match slf.device_holder.pending_drm_devices.remove(&devnum) {
|
||||||
Some(d) if d.id == id => d,
|
Some(d) if d.id == id => d,
|
||||||
_ => return,
|
_ => return,
|
||||||
|
|
@ -303,7 +305,7 @@ impl MetalBackend {
|
||||||
self.device_holder
|
self.device_holder
|
||||||
.devices
|
.devices
|
||||||
.set(devnum, MetalDevice::Input(dev));
|
.set(devnum, MetalDevice::Input(dev));
|
||||||
self.session.get_device(devnum, move |res| {
|
self.get_device(devnum, move |res| {
|
||||||
let id = &slf.device_holder.devices;
|
let id = &slf.device_holder.devices;
|
||||||
let mut slots = slf.device_holder.input_devices.borrow_mut();
|
let mut slots = slf.device_holder.input_devices.borrow_mut();
|
||||||
let dev = 'dev: {
|
let dev = 'dev: {
|
||||||
|
|
@ -345,4 +347,23 @@ impl MetalBackend {
|
||||||
});
|
});
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_device<F>(self: &Rc<Self>, dev: c::dev_t, f: F)
|
||||||
|
where
|
||||||
|
F: FnOnce(Result<&TakeDeviceReply, DbusError>) + 'static,
|
||||||
|
{
|
||||||
|
self.device_holder.num_pending_devices.fetch_add(1);
|
||||||
|
let slf = self.clone();
|
||||||
|
self.session.get_device(dev, move |res| {
|
||||||
|
let rem = slf.device_holder.num_pending_devices.fetch_sub(1);
|
||||||
|
f(res);
|
||||||
|
if rem == 1 {
|
||||||
|
slf.state
|
||||||
|
.backend_events
|
||||||
|
.push(BackendEvent::DevicesEnumerated);
|
||||||
|
// Set to 1 to ensure this branch is never taken again.
|
||||||
|
slf.device_holder.num_pending_devices.set(1);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -299,6 +299,10 @@ impl XBackend {
|
||||||
self.active_output(output).await;
|
self.active_output(output).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.state
|
||||||
|
.backend_events
|
||||||
|
.push(BackendEvent::DevicesEnumerated);
|
||||||
|
|
||||||
pending().await
|
pending().await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,10 @@ impl ConfigProxy {
|
||||||
self.send(&ServerMessage::GraphicsInitialized);
|
self.send(&ServerMessage::GraphicsInitialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn devices_enumerated(&self) {
|
||||||
|
self.send(&ServerMessage::DevicesEnumerated);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn clear(&self) {
|
pub fn clear(&self) {
|
||||||
self.send(&ServerMessage::Clear);
|
self.send(&ServerMessage::Clear);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,7 @@ unsafe extern "C" fn handle_msg(data: *const u8, msg: *const u8, size: usize) {
|
||||||
ServerMessage::NewDrmDev { .. } => {}
|
ServerMessage::NewDrmDev { .. } => {}
|
||||||
ServerMessage::DelDrmDev { .. } => {}
|
ServerMessage::DelDrmDev { .. } => {}
|
||||||
ServerMessage::Idle => {}
|
ServerMessage::Idle => {}
|
||||||
|
ServerMessage::DevicesEnumerated => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -268,6 +268,12 @@ impl State {
|
||||||
self.reload_cursors();
|
self.reload_cursors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn devices_enumerated(&self) {
|
||||||
|
if let Some(config) = self.config.get() {
|
||||||
|
config.devices_enumerated()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_render_ctx(&self, ctx: Option<&Rc<RenderContext>>) {
|
pub fn set_render_ctx(&self, ctx: Option<&Rc<RenderContext>>) {
|
||||||
self.render_ctx.set(ctx.cloned());
|
self.render_ctx.set(ctx.cloned());
|
||||||
self.render_ctx_version.fetch_add(1);
|
self.render_ctx_version.fetch_add(1);
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ impl BackendEventHandler {
|
||||||
BackendEvent::NewConnector(connector) => connector::handle(&self.state, &connector),
|
BackendEvent::NewConnector(connector) => connector::handle(&self.state, &connector),
|
||||||
BackendEvent::NewInputDevice(s) => input_device::handle(&self.state, s),
|
BackendEvent::NewInputDevice(s) => input_device::handle(&self.state, s),
|
||||||
BackendEvent::NewDrmDevice(d) => drmdev::handle(&self.state, d),
|
BackendEvent::NewDrmDevice(d) => drmdev::handle(&self.state, d),
|
||||||
|
BackendEvent::DevicesEnumerated => self.state.devices_enumerated(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue