1
0
Fork 0
forked from wry/wry
wry/src/ifs/zwp_primary_selection_source_v1/mod.rs
2022-02-05 18:14:24 +01:00

142 lines
3.8 KiB
Rust

mod types;
use crate::client::{Client, DynEventFormatter};
use crate::ifs::wl_seat::WlSeatGlobal;
use crate::ifs::zwp_primary_selection_offer_v1::ZwpPrimarySelectionOfferV1;
use crate::object::Object;
use crate::utils::buffd::MsgParser;
use crate::utils::clonecell::CloneCell;
use ahash::AHashSet;
use std::cell::RefCell;
use std::rc::Rc;
pub use types::*;
use uapi::OwnedFd;
const OFFER: u32 = 0;
const DESTROY: u32 = 1;
const SEND: u32 = 0;
const CANCELLED: u32 = 1;
id!(ZwpPrimarySelectionSourceV1Id);
pub struct ZwpPrimarySelectionSourceV1 {
pub id: ZwpPrimarySelectionSourceV1Id,
pub client: Rc<Client>,
pub mime_types: RefCell<AHashSet<String>>,
seat: CloneCell<Option<Rc<WlSeatGlobal>>>,
offer: CloneCell<Option<Rc<ZwpPrimarySelectionOfferV1>>>,
}
impl ZwpPrimarySelectionSourceV1 {
pub fn new(id: ZwpPrimarySelectionSourceV1Id, client: &Rc<Client>) -> Self {
Self {
id,
client: client.clone(),
mime_types: RefCell::new(Default::default()),
seat: Default::default(),
offer: Default::default(),
}
}
pub fn attach(&self, seat: &Rc<WlSeatGlobal>) -> Result<(), ZwpPrimarySelectionSourceV1Error> {
if self.seat.get().is_some() {
return Err(ZwpPrimarySelectionSourceV1Error::AlreadyAttached);
}
self.seat.set(Some(seat.clone()));
Ok(())
}
pub fn detach(self: &Rc<Self>) {
self.seat.set(None);
if let Some(offer) = self.offer.set(None) {
offer.source.set(None);
}
self.client.event(self.cancelled());
self.client.flush();
}
pub fn create_offer(self: &Rc<Self>, client: &Rc<Client>) {
let seat = match self.seat.get() {
Some(a) => a,
_ => {
log::error!("Trying to create an offer from a unattached data source");
return;
}
};
let offer = ZwpPrimarySelectionOfferV1::create(client, self, &seat);
let old = self.offer.set(offer);
if let Some(offer) = old {
offer.source.set(None);
}
}
pub fn clear_offer(&self) {
self.offer.take();
}
pub fn cancelled(self: &Rc<Self>) -> DynEventFormatter {
Box::new(Cancelled { obj: self.clone() })
}
pub fn send(self: &Rc<Self>, mime_type: &str, fd: OwnedFd) -> DynEventFormatter {
Box::new(Send {
obj: self.clone(),
mime_type: mime_type.to_string(),
fd: Rc::new(fd),
})
}
fn offer(&self, parser: MsgParser<'_, '_>) -> Result<(), OfferError> {
let req: Offer = self.client.parse(self, parser)?;
if self
.mime_types
.borrow_mut()
.insert(req.mime_type.to_string())
{
if let Some(offer) = self.offer.get() {
offer.client.event(offer.offer(req.mime_type));
}
}
Ok(())
}
fn disconnect(&self) {
if let Some(offer) = self.offer.take() {
offer.source.set(None);
}
if let Some(seat) = self.seat.get() {
let _ = seat.set_primary_selection(None);
}
}
fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), DestroyError> {
let _req: Destroy = self.client.parse(self, parser)?;
self.disconnect();
self.client.remove_obj(self)?;
Ok(())
}
}
object_base! {
ZwpPrimarySelectionSourceV1, ZwpPrimarySelectionSourceV1Error;
OFFER => offer,
DESTROY => destroy,
}
impl Object for ZwpPrimarySelectionSourceV1 {
fn num_requests(&self) -> u32 {
DESTROY + 1
}
fn break_loops(&self) {
self.disconnect();
}
}
dedicated_add_obj!(
ZwpPrimarySelectionSourceV1,
ZwpPrimarySelectionSourceV1Id,
zwp_primary_selection_source
);