1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
use wayland_protocols::unstable::primary_selection::v1::client::zwp_primary_selection_source_v1::{
self, ZwpPrimarySelectionSourceV1,
};
use wayland_protocols::misc::gtk_primary_selection::client::gtk_primary_selection_source::{
self, GtkPrimarySelectionSource,
};
use crate::data_device::WritePipe;
use std::os::unix::io::FromRawFd;
use wayland_client::DispatchData;
use super::PrimarySelectionDeviceManager;
pub struct PrimarySelectionSource {
pub(crate) source: PrimarySelectionSourceImpl,
}
pub enum PrimarySelectionSourceEvent {
Send {
mime_type: String,
pipe: WritePipe,
},
Cancelled,
}
impl PrimarySelectionSource {
pub fn new<F, S, It>(
manager: &PrimarySelectionDeviceManager,
mime_types: It,
mut callback: F,
) -> Self
where
F: FnMut(PrimarySelectionSourceEvent, DispatchData) + 'static,
S: Into<String>,
It: IntoIterator<Item = S>,
{
match manager {
PrimarySelectionDeviceManager::Zwp(ref manager) => {
let source = manager.create_source();
source.quick_assign(move |source, event, dispatch_data| {
zwp_primary_source_imp(&source, event, dispatch_data, &mut callback);
});
for mime in mime_types {
source.offer(mime.into());
}
Self { source: PrimarySelectionSourceImpl::Zwp(source.detach()) }
}
PrimarySelectionDeviceManager::Gtk(ref manager) => {
let source = manager.create_source();
source.quick_assign(move |source, event, dispatch_data| {
gtk_primary_source_imp(&source, event, dispatch_data, &mut callback);
});
for mime in mime_types {
source.offer(mime.into());
}
Self { source: PrimarySelectionSourceImpl::Gtk(source.detach()) }
}
}
}
}
pub(crate) enum PrimarySelectionSourceImpl {
Zwp(ZwpPrimarySelectionSourceV1),
Gtk(GtkPrimarySelectionSource),
}
fn gtk_primary_source_imp<Impl>(
source: &GtkPrimarySelectionSource,
event: gtk_primary_selection_source::Event,
dispatch_data: DispatchData,
implem: &mut Impl,
) where
Impl: FnMut(PrimarySelectionSourceEvent, DispatchData),
{
use gtk_primary_selection_source::Event;
let event = match event {
Event::Send { mime_type, fd } => PrimarySelectionSourceEvent::Send {
mime_type,
pipe: unsafe { FromRawFd::from_raw_fd(fd) },
},
Event::Cancelled => {
source.destroy();
PrimarySelectionSourceEvent::Cancelled
}
_ => unreachable!(),
};
implem(event, dispatch_data);
}
fn zwp_primary_source_imp<Impl>(
source: &ZwpPrimarySelectionSourceV1,
event: zwp_primary_selection_source_v1::Event,
dispatch_data: DispatchData,
implem: &mut Impl,
) where
Impl: FnMut(PrimarySelectionSourceEvent, DispatchData),
{
use zwp_primary_selection_source_v1::Event;
let event = match event {
Event::Send { mime_type, fd } => PrimarySelectionSourceEvent::Send {
mime_type,
pipe: unsafe { FromRawFd::from_raw_fd(fd) },
},
Event::Cancelled => {
source.destroy();
PrimarySelectionSourceEvent::Cancelled
}
_ => unreachable!(),
};
implem(event, dispatch_data);
}