1
0
Fork 0
forked from wry/wry

x: add XDrmDevice

This commit is contained in:
Julian Orth 2022-11-13 13:11:55 +01:00
parent e29fd0e70c
commit dddd68ba06

View file

@ -2,10 +2,10 @@ use {
crate::{ crate::{
async_engine::{Phase, SpawnedFuture}, async_engine::{Phase, SpawnedFuture},
backend::{ backend::{
AxisSource, Backend, BackendEvent, Connector, ConnectorEvent, ConnectorId, AxisSource, Backend, BackendDrmDevice, BackendEvent, Connector, ConnectorEvent,
ConnectorKernelId, DrmDeviceId, InputDevice, InputDeviceAccelProfile, ConnectorId, ConnectorKernelId, DrmDeviceId, DrmEvent, InputDevice,
InputDeviceCapability, InputDeviceId, InputEvent, KeyState, Mode, MonitorInfo, InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId, InputEvent, KeyState,
ScrollAxis, TransformMatrix, AXIS_120, Mode, MonitorInfo, ScrollAxis, TransformMatrix, AXIS_120,
}, },
fixed::Fixed, fixed::Fixed,
format::XRGB8888, format::XRGB8888,
@ -59,6 +59,7 @@ use {
rc::Rc, rc::Rc,
}, },
thiserror::Error, thiserror::Error,
uapi::{c::dev_t, Errno},
}; };
#[derive(Debug, Error)] #[derive(Debug, Error)]
@ -113,6 +114,8 @@ pub enum XBackendError {
MapWindow(#[source] XconError), MapWindow(#[source] XconError),
#[error("Could not query device")] #[error("Could not query device")]
QueryDevice(#[source] XconError), QueryDevice(#[source] XconError),
#[error("Could not fstat the drm device")]
DrmDeviceFstat(#[source] Errno),
} }
pub async fn create(state: &Rc<State>) -> Result<Rc<XBackend>, XBackendError> { pub async fn create(state: &Rc<State>) -> Result<Rc<XBackend>, XBackendError> {
@ -169,6 +172,10 @@ pub async fn create(state: &Rc<State>) -> Result<Rc<XBackend>, XBackendError> {
Err(e) => return Err(XBackendError::DriOpen(e)), Err(e) => return Err(XBackendError::DriOpen(e)),
} }
}; };
let drm_dev = match uapi::fstat(drm.raw()) {
Ok(s) => s.st_rdev,
Err(e) => return Err(XBackendError::DrmDeviceFstat(e)),
};
let gbm = GbmDevice::new(&drm)?; let gbm = GbmDevice::new(&drm)?;
let ctx = match RenderContext::from_drm_device(&drm) { let ctx = match RenderContext::from_drm_device(&drm) {
Ok(r) => Rc::new(r), Ok(r) => Rc::new(r),
@ -230,6 +237,8 @@ pub async fn create(state: &Rc<State>) -> Result<Rc<XBackend>, XBackendError> {
scheduled_present: Default::default(), scheduled_present: Default::default(),
grab_requests: Default::default(), grab_requests: Default::default(),
render_result: Default::default(), render_result: Default::default(),
drm_device_id: state.drm_dev_ids.next(),
drm_dev,
}); });
data.add_output().await?; data.add_output().await?;
@ -263,6 +272,8 @@ pub struct XBackend {
scheduled_present: AsyncQueue<Rc<XOutput>>, scheduled_present: AsyncQueue<Rc<XOutput>>,
grab_requests: AsyncQueue<(Rc<XSeat>, bool)>, grab_requests: AsyncQueue<(Rc<XSeat>, bool)>,
render_result: RefCell<RenderResult>, render_result: RefCell<RenderResult>,
drm_device_id: DrmDeviceId,
drm_dev: dev_t,
} }
impl XBackend { impl XBackend {
@ -277,6 +288,16 @@ impl XBackend {
.spawn2(Phase::Present, self.clone().present_handler()); .spawn2(Phase::Present, self.clone().present_handler());
self.state.set_render_ctx(Some(&self.ctx)); self.state.set_render_ctx(Some(&self.ctx));
self.state
.backend_events
.push(BackendEvent::NewDrmDevice(Rc::new(XDrmDevice {
_backend: self.clone(),
id: self.drm_device_id,
dev: self.drm_dev,
})));
for (_, output) in self.outputs.lock().iter() {
self.active_output(output).await;
}
pending().await pending().await
} }
@ -428,7 +449,7 @@ impl XBackend {
let images = self.create_images(window_id, WIDTH, HEIGHT).await?; let images = self.create_images(window_id, WIDTH, HEIGHT).await?;
let output = Rc::new(XOutput { let output = Rc::new(XOutput {
id: self.state.connector_ids.next(), id: self.state.connector_ids.next(),
_backend: self.clone(), backend: self.clone(),
window: window_id, window: window_id,
events: Default::default(), events: Default::default(),
width: Cell::new(0), width: Cell::new(0),
@ -511,25 +532,28 @@ impl XBackend {
} }
} }
self.outputs.set(window_id, output.clone()); self.outputs.set(window_id, output.clone());
Ok(())
}
async fn active_output(&self, output: &Rc<XOutput>) {
self.state self.state
.backend_events .backend_events
.push(BackendEvent::NewConnector(output.clone())); .push(BackendEvent::NewConnector(output.clone()));
output.events.push(ConnectorEvent::Connected(MonitorInfo { output.events.push(ConnectorEvent::Connected(MonitorInfo {
modes: vec![], modes: vec![],
manufacturer: "X.Org Foundation".to_string(), manufacturer: "X.Org Foundation".to_string(),
product: format!("X-Window-{}", window_id), product: format!("X-Window-{}", output.window),
serial_number: window_id.to_string(), serial_number: output.window.to_string(),
initial_mode: Mode { initial_mode: Mode {
width: WIDTH, width: output.width.get(),
height: HEIGHT, height: output.height.get(),
refresh_rate_millihz: 60_000, // TODO refresh_rate_millihz: 60_000, // TODO
}, },
width_mm: WIDTH, width_mm: output.width.get(),
height_mm: HEIGHT, height_mm: output.height.get(),
})); }));
output.changed(); output.changed();
self.present(&output).await; self.present(&output).await;
Ok(())
} }
async fn query_devices(self: &Rc<Self>, deviceid: u16) -> Result<(), XBackendError> { async fn query_devices(self: &Rc<Self>, deviceid: u16) -> Result<(), XBackendError> {
@ -910,9 +934,33 @@ impl XBackend {
} }
} }
struct XDrmDevice {
_backend: Rc<XBackend>,
id: DrmDeviceId,
dev: dev_t,
}
impl BackendDrmDevice for XDrmDevice {
fn id(&self) -> DrmDeviceId {
self.id
}
fn event(&self) -> Option<DrmEvent> {
None
}
fn on_change(&self, _cb: Rc<dyn Fn()>) {
// nothing
}
fn dev_t(&self) -> dev_t {
self.dev
}
}
struct XOutput { struct XOutput {
id: ConnectorId, id: ConnectorId,
_backend: Rc<XBackend>, backend: Rc<XBackend>,
window: u32, window: u32,
events: SyncQueue<ConnectorEvent>, events: SyncQueue<ConnectorEvent>,
width: Cell<i32>, width: Cell<i32>,
@ -966,7 +1014,7 @@ impl Connector for XOutput {
} }
fn drm_dev(&self) -> Option<DrmDeviceId> { fn drm_dev(&self) -> Option<DrmDeviceId> {
None Some(self.backend.drm_device_id)
} }
fn set_enabled(&self, _enabled: bool) { fn set_enabled(&self, _enabled: bool) {