| 1 | use std::{ |
| 2 | os::unix::io::{AsFd, OwnedFd}, |
| 3 | sync::Mutex, |
| 4 | }; |
| 5 | |
| 6 | use crate::reexports::client::{Connection, Dispatch, QueueHandle, Proxy}; |
| 7 | use crate::reexports::protocols::wp::primary_selection::zv1::client::zwp_primary_selection_offer_v1::ZwpPrimarySelectionOfferV1; |
| 8 | |
| 9 | use crate::data_device_manager::ReadPipe; |
| 10 | |
| 11 | use super::PrimarySelectionManagerState; |
| 12 | |
| 13 | /// Wrapper around the [`ZwpPrimarySelectionOfferV1`]. |
| 14 | #[derive (Debug, Clone, PartialEq, Eq)] |
| 15 | pub struct PrimarySelectionOffer { |
| 16 | pub(crate) offer: ZwpPrimarySelectionOfferV1, |
| 17 | } |
| 18 | |
| 19 | impl PrimarySelectionOffer { |
| 20 | /// Inspect the mime types available on the given offer. |
| 21 | pub fn with_mime_types<T, F: Fn(&[String]) -> T>(&self, callback: F) -> T { |
| 22 | let mime_types = |
| 23 | self.offer.data::<PrimarySelectionOfferData>().unwrap().mimes.lock().unwrap(); |
| 24 | callback(mime_types.as_ref()) |
| 25 | } |
| 26 | |
| 27 | /// Request to receive the data of a given mime type. |
| 28 | /// |
| 29 | /// You can call this function several times. |
| 30 | /// |
| 31 | /// Note that you should *not* read the contents right away in a |
| 32 | /// blocking way, as you may deadlock your application doing so. |
| 33 | /// At least make sure you flush your events to the server before |
| 34 | /// doing so. |
| 35 | /// |
| 36 | /// Fails if too many file descriptors were already open and a pipe |
| 37 | /// could not be created. |
| 38 | pub fn receive(&self, mime_type: String) -> std::io::Result<ReadPipe> { |
| 39 | use rustix::pipe::{pipe_with, PipeFlags}; |
| 40 | // create a pipe |
| 41 | let (readfd, writefd) = pipe_with(PipeFlags::CLOEXEC)?; |
| 42 | |
| 43 | self.receive_to_fd(mime_type, writefd); |
| 44 | |
| 45 | Ok(ReadPipe::from(readfd)) |
| 46 | } |
| 47 | |
| 48 | /// Request to receive the data of a given mime type, writen to `writefd`. |
| 49 | /// |
| 50 | /// The provided file destructor must be a valid FD for writing, and will be closed |
| 51 | /// once the contents are written. |
| 52 | pub fn receive_to_fd(&self, mime_type: String, writefd: OwnedFd) { |
| 53 | self.offer.receive(mime_type, writefd.as_fd()); |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | impl<State> Dispatch<ZwpPrimarySelectionOfferV1, PrimarySelectionOfferData, State> |
| 58 | for PrimarySelectionManagerState |
| 59 | where |
| 60 | State: Dispatch<ZwpPrimarySelectionOfferV1, PrimarySelectionOfferData>, |
| 61 | { |
| 62 | fn event( |
| 63 | _: &mut State, |
| 64 | _: &ZwpPrimarySelectionOfferV1, |
| 65 | event: <ZwpPrimarySelectionOfferV1 as wayland_client::Proxy>::Event, |
| 66 | data: &PrimarySelectionOfferData, |
| 67 | _: &Connection, |
| 68 | _: &QueueHandle<State>, |
| 69 | ) { |
| 70 | use wayland_protocols::wp::primary_selection::zv1::client::zwp_primary_selection_offer_v1::Event; |
| 71 | match event { |
| 72 | Event::Offer { mime_type: String } => { |
| 73 | data.mimes.lock().unwrap().push(mime_type); |
| 74 | } |
| 75 | _ => unreachable!(), |
| 76 | } |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | /// The data associated with the [`ZwpPrimarySelectionOfferV1`]. |
| 81 | #[derive (Debug, Default)] |
| 82 | pub struct PrimarySelectionOfferData { |
| 83 | mimes: Mutex<Vec<String>>, |
| 84 | } |
| 85 | |