smithay_client_toolkit/data_device_manager/
write_pipe.rs

1use std::{
2    fs, io,
3    os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd},
4};
5
6/// If the `calloop` cargo feature is enabled, this can be used
7/// as an `EventSource` in a calloop event loop.
8#[must_use]
9#[derive(Debug)]
10pub struct WritePipe {
11    #[cfg(feature = "calloop")]
12    file: calloop::generic::Generic<fs::File>,
13    #[cfg(not(feature = "calloop"))]
14    file: fs::File,
15}
16
17#[cfg(feature = "calloop")]
18impl io::Write for WritePipe {
19    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
20        unsafe { self.file.get_mut().write(buf) }
21    }
22
23    fn flush(&mut self) -> io::Result<()> {
24        unsafe { self.file.get_mut().flush() }
25    }
26}
27
28#[cfg(not(feature = "calloop"))]
29impl io::Write for WritePipe {
30    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
31        self.file.write(buf)
32    }
33
34    fn flush(&mut self) -> io::Result<()> {
35        self.file.flush()
36    }
37}
38
39#[cfg(feature = "calloop")]
40impl FromRawFd for WritePipe {
41    unsafe fn from_raw_fd(fd: RawFd) -> WritePipe {
42        WritePipe {
43            file: calloop::generic::Generic::new(
44                unsafe { FromRawFd::from_raw_fd(fd) },
45                calloop::Interest::WRITE,
46                calloop::Mode::Level,
47            ),
48        }
49    }
50}
51
52#[cfg(feature = "calloop")]
53impl From<OwnedFd> for WritePipe {
54    fn from(owned: OwnedFd) -> Self {
55        WritePipe {
56            file: calloop::generic::Generic::new(
57                owned.into(),
58                calloop::Interest::WRITE,
59                calloop::Mode::Level,
60            ),
61        }
62    }
63}
64
65#[cfg(not(feature = "calloop"))]
66impl FromRawFd for WritePipe {
67    unsafe fn from_raw_fd(fd: RawFd) -> WritePipe {
68        WritePipe { file: unsafe { FromRawFd::from_raw_fd(fd) } }
69    }
70}
71
72#[cfg(not(feature = "calloop"))]
73impl From<OwnedFd> for WritePipe {
74    fn from(owned: OwnedFd) -> Self {
75        WritePipe { file: owned.into() }
76    }
77}
78
79#[cfg(feature = "calloop")]
80impl AsRawFd for WritePipe {
81    fn as_raw_fd(&self) -> RawFd {
82        self.file.get_ref().as_raw_fd()
83    }
84}
85
86#[cfg(feature = "calloop")]
87impl AsFd for WritePipe {
88    fn as_fd(&self) -> BorrowedFd {
89        self.file.get_ref().as_fd()
90    }
91}
92
93#[cfg(not(feature = "calloop"))]
94impl AsRawFd for WritePipe {
95    fn as_raw_fd(&self) -> RawFd {
96        self.file.as_raw_fd()
97    }
98}
99#[cfg(not(feature = "calloop"))]
100
101impl AsFd for WritePipe {
102    fn as_fd(&self) -> BorrowedFd<'_> {
103        self.file.as_fd()
104    }
105}
106
107#[cfg(feature = "calloop")]
108impl IntoRawFd for WritePipe {
109    fn into_raw_fd(self) -> RawFd {
110        self.file.unwrap().into_raw_fd()
111    }
112}
113
114#[cfg(feature = "calloop")]
115impl From<WritePipe> for OwnedFd {
116    fn from(write_pipe: WritePipe) -> Self {
117        write_pipe.file.unwrap().into()
118    }
119}
120
121#[cfg(not(feature = "calloop"))]
122impl IntoRawFd for WritePipe {
123    fn into_raw_fd(self) -> RawFd {
124        self.file.into_raw_fd()
125    }
126}
127
128#[cfg(not(feature = "calloop"))]
129impl From<WritePipe> for OwnedFd {
130    fn from(write_pipe: WritePipe) -> Self {
131        write_pipe.file.into()
132    }
133}
134
135#[cfg(feature = "calloop")]
136impl calloop::EventSource for WritePipe {
137    type Event = ();
138    type Error = std::io::Error;
139    type Metadata = calloop::generic::NoIoDrop<fs::File>;
140    type Ret = calloop::PostAction;
141
142    fn process_events<F>(
143        &mut self,
144        readiness: calloop::Readiness,
145        token: calloop::Token,
146        mut callback: F,
147    ) -> std::io::Result<calloop::PostAction>
148    where
149        F: FnMut((), &mut calloop::generic::NoIoDrop<fs::File>) -> Self::Ret,
150    {
151        self.file.process_events(readiness, token, |_, file| Ok(callback((), file)))
152    }
153
154    fn register(
155        &mut self,
156        poll: &mut calloop::Poll,
157        token_factory: &mut calloop::TokenFactory,
158    ) -> calloop::Result<()> {
159        self.file.register(poll, token_factory)
160    }
161
162    fn reregister(
163        &mut self,
164        poll: &mut calloop::Poll,
165        token_factory: &mut calloop::TokenFactory,
166    ) -> calloop::Result<()> {
167        self.file.reregister(poll, token_factory)
168    }
169
170    fn unregister(&mut self, poll: &mut calloop::Poll) -> calloop::Result<()> {
171        self.file.unregister(poll)
172    }
173}