jay-compositor 1.15.0

The Jay compositor
use crate::backend::ConnectorId;
use crate::backend::DrmDeviceId;
use crate::client::Client;
use crate::client::LookupError;
use crate::ifs::wp_drm_lease_v1::WpDrmLeaseV1;
use crate::ifs::wp_drm_lease_v1::WpDrmLeaseV1Lessee;
use crate::leaks::Tracker;
use crate::object::Version;
use crate::utils::copyhashmap::CopyHashMap;
use crate::wire::WpDrmLeaseConnectorV1Id;
use crate::wire::WpDrmLeaseRequestV1Id;
use crate::wire::wp_drm_lease_request_v1::*;
use jay_proc::Object;
use std::cell::Cell;
use std::rc::Rc;
use thiserror::Error;

#[derive(Object)]
pub struct WpDrmLeaseRequestV1 {
    pub id: WpDrmLeaseRequestV1Id,
    pub client: Rc<Client>,
    pub tracker: Tracker<Self>,
    pub version: Version,
    pub device: DrmDeviceId,
    pub connectors: CopyHashMap<WpDrmLeaseConnectorV1Id, ConnectorId>,
}

impl WpDrmLeaseRequestV1RequestHandler for WpDrmLeaseRequestV1 {
    type Error = WpDrmLeaseRequestV1Error;

    fn request_connector(&self, req: RequestConnector, _slf: &Rc<Self>) -> Result<(), Self::Error> {
        let c = self.client.lookup(req.connector)?;
        if self.device != c.device.device {
            return Err(WpDrmLeaseRequestV1Error::MismatchedDevice(c.id));
        }
        if self.connectors.contains(&c.id) {
            return Err(WpDrmLeaseRequestV1Error::RepeatedDevice(c.id));
        }
        self.connectors.set(c.id, c.connector_id);
        Ok(())
    }

    fn submit(&self, req: Submit, _slf: &Rc<Self>) -> Result<(), Self::Error> {
        self.client.remove_obj(self);
        let obj = Rc::new(WpDrmLeaseV1 {
            id: req.id,
            client: self.client.clone(),
            tracker: Default::default(),
            version: self.version,
            finished: Cell::new(false),
            lease: Default::default(),
        });
        track!(self.client, obj);
        self.client.add_client_obj(&obj);
        if self.connectors.is_empty() {
            return Err(WpDrmLeaseRequestV1Error::EmptyLease);
        }
        let Some(dev) = self.client.state.drm_devs.get(&self.device) else {
            obj.send_finished();
            return Ok(());
        };
        let lessee = Rc::new(WpDrmLeaseV1Lessee { obj });
        let connectors: Vec<_> = self.connectors.lock().values().copied().collect();
        dev.dev.clone().create_lease(lessee, &connectors);
        Ok(())
    }
}

#[derive(Debug, Error)]
pub enum WpDrmLeaseRequestV1Error {
    #[error(transparent)]
    Lookup(#[from] LookupError),
    #[error("Connector {0} does not belong to this device")]
    MismatchedDevice(WpDrmLeaseConnectorV1Id),
    #[error("Connector {0} is already part of this request")]
    RepeatedDevice(WpDrmLeaseConnectorV1Id),
    #[error("Lease request is empty")]
    EmptyLease,
}