dnd/platform/
linux.rs

1use std::{borrow::Cow, ffi::c_void, sync::Arc};
2
3use crate::{DataWrapper, DndAction, DndSurface, Icon};
4use raw_window_handle::HasWindowHandle;
5use smithay_clipboard::mime::{AllowedMimeTypes, AsMimeTypes, MimeType};
6
7impl<
8        T: mime::AllowedMimeTypes
9            + std::convert::TryFrom<(std::vec::Vec<u8>, String)>,
10    > AllowedMimeTypes for DataWrapper<T>
11{
12    fn allowed() -> Cow<'static, [MimeType]> {
13        T::allowed()
14            .into_iter()
15            .map(|s| MimeType::from(Cow::Owned(s.to_string())))
16            .collect()
17    }
18}
19
20impl<T: TryFrom<(Vec<u8>, String)>> TryFrom<(Vec<u8>, MimeType)>
21    for DataWrapper<T>
22{
23    type Error = T::Error;
24
25    fn try_from(
26        (data, mime): (Vec<u8>, MimeType),
27    ) -> Result<Self, Self::Error> {
28        T::try_from((data, mime.to_string())).map(|d| DataWrapper(d))
29    }
30}
31
32impl<T: mime::AsMimeTypes> AsMimeTypes for DataWrapper<T> {
33    fn available(&self) -> Cow<'static, [MimeType]> {
34        self.0
35            .available()
36            .into_iter()
37            .map(|m| MimeType::from(Cow::Owned(m.to_string())))
38            .collect()
39    }
40
41    fn as_bytes(&self, mime_type: &MimeType) -> Option<Cow<'static, [u8]>> {
42        self.0.as_bytes(mime_type.as_ref())
43    }
44}
45
46impl smithay_clipboard::dnd::RawSurface for DndSurface {
47    unsafe fn get_ptr(&mut self) -> *mut c_void {
48        self.0.window_handle().unwrap().get_ptr()
49    }
50}
51
52impl From<sctk::reexports::client::protocol::wl_data_device_manager::DndAction>
53    for DndAction
54{
55    fn from(
56        action: sctk::reexports::client::protocol::wl_data_device_manager::DndAction,
57    ) -> Self {
58        let mut a = DndAction::empty();
59        if action.contains(sctk::reexports::client::protocol::wl_data_device_manager::DndAction::Copy) {
60        a |= DndAction::Copy;
61    }
62        if action.contains(sctk::reexports::client::protocol::wl_data_device_manager::DndAction::Move) {
63        a |= DndAction::Move;
64    }
65        if action.contains(sctk::reexports::client::protocol::wl_data_device_manager::DndAction::Ask) {
66        a |= DndAction::Ask;
67    }
68        a
69    }
70}
71
72impl From<DndAction>
73    for sctk::reexports::client::protocol::wl_data_device_manager::DndAction
74{
75    fn from(action: DndAction) -> Self {
76        let mut a = sctk::reexports::client::protocol::wl_data_device_manager::DndAction::empty();
77        if action.contains(DndAction::Copy) {
78            a |= sctk::reexports::client::protocol::wl_data_device_manager::DndAction::Copy;
79        }
80        if action.contains(DndAction::Move) {
81            a |= sctk::reexports::client::protocol::wl_data_device_manager::DndAction::Move;
82        }
83        if action.contains(DndAction::Ask) {
84            a |= sctk::reexports::client::protocol::wl_data_device_manager::DndAction::Ask;
85        }
86        a
87    }
88}
89
90impl From<Icon> for smithay_clipboard::dnd::Icon<DndSurface> {
91    fn from(icon: Icon) -> Self {
92        match icon {
93            Icon::Surface(surface) => {
94                smithay_clipboard::dnd::Icon::Surface(surface)
95            }
96            Icon::Buffer {
97                data,
98                width,
99                height,
100                transparent,
101            } => smithay_clipboard::dnd::Icon::Buf {
102                data: Arc::try_unwrap(data)
103                    .unwrap_or_else(|d| d.as_ref().clone()),
104                width,
105                height,
106                transparent,
107            },
108        }
109    }
110}