smithay_client_toolkit/data_device_manager/
read_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 ReadPipe {
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::Read for ReadPipe {
19    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
20        unsafe { self.file.get_mut().read(buf) }
21    }
22}
23
24#[cfg(not(feature = "calloop"))]
25impl io::Read for ReadPipe {
26    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
27        self.file.read(buf)
28    }
29}
30
31#[cfg(feature = "calloop")]
32impl FromRawFd for ReadPipe {
33    unsafe fn from_raw_fd(fd: RawFd) -> ReadPipe {
34        ReadPipe {
35            file: calloop::generic::Generic::new(
36                unsafe { FromRawFd::from_raw_fd(fd) },
37                calloop::Interest::READ,
38                calloop::Mode::Level,
39            ),
40        }
41    }
42}
43
44#[cfg(feature = "calloop")]
45impl From<OwnedFd> for ReadPipe {
46    fn from(owned: OwnedFd) -> Self {
47        ReadPipe {
48            file: calloop::generic::Generic::new(
49                owned.into(),
50                calloop::Interest::READ,
51                calloop::Mode::Level,
52            ),
53        }
54    }
55}
56
57#[cfg(not(feature = "calloop"))]
58impl FromRawFd for ReadPipe {
59    unsafe fn from_raw_fd(fd: RawFd) -> ReadPipe {
60        ReadPipe { file: unsafe { FromRawFd::from_raw_fd(fd) } }
61    }
62}
63
64#[cfg(not(feature = "calloop"))]
65impl From<OwnedFd> for ReadPipe {
66    fn from(owned: OwnedFd) -> Self {
67        ReadPipe { file: owned.into() }
68    }
69}
70
71#[cfg(feature = "calloop")]
72impl AsRawFd for ReadPipe {
73    fn as_raw_fd(&self) -> RawFd {
74        self.file.get_ref().as_raw_fd()
75    }
76}
77
78#[cfg(feature = "calloop")]
79impl AsFd for ReadPipe {
80    fn as_fd(&self) -> BorrowedFd<'_> {
81        self.file.get_ref().as_fd()
82    }
83}
84
85#[cfg(not(feature = "calloop"))]
86impl AsRawFd for ReadPipe {
87    fn as_raw_fd(&self) -> RawFd {
88        self.file.as_raw_fd()
89    }
90}
91#[cfg(not(feature = "calloop"))]
92
93impl AsFd for ReadPipe {
94    fn as_fd(&self) -> BorrowedFd<'_> {
95        self.file.as_fd()
96    }
97}
98
99#[cfg(feature = "calloop")]
100impl IntoRawFd for ReadPipe {
101    fn into_raw_fd(self) -> RawFd {
102        self.file.unwrap().as_raw_fd()
103    }
104}
105
106#[cfg(feature = "calloop")]
107impl From<ReadPipe> for OwnedFd {
108    fn from(read_pipe: ReadPipe) -> Self {
109        read_pipe.file.unwrap().into()
110    }
111}
112
113#[cfg(not(feature = "calloop"))]
114impl IntoRawFd for ReadPipe {
115    fn into_raw_fd(self) -> RawFd {
116        self.file.into_raw_fd()
117    }
118}
119
120#[cfg(not(feature = "calloop"))]
121impl From<ReadPipe> for OwnedFd {
122    fn from(read_pipe: ReadPipe) -> Self {
123        read_pipe.file.into()
124    }
125}
126
127#[cfg(feature = "calloop")]
128impl calloop::EventSource for ReadPipe {
129    type Event = ();
130    type Error = std::io::Error;
131    type Metadata = calloop::generic::NoIoDrop<fs::File>;
132    type Ret = calloop::PostAction;
133
134    fn process_events<F>(
135        &mut self,
136        readiness: calloop::Readiness,
137        token: calloop::Token,
138        mut callback: F,
139    ) -> std::io::Result<calloop::PostAction>
140    where
141        F: FnMut((), &mut calloop::generic::NoIoDrop<fs::File>) -> Self::Ret,
142    {
143        self.file.process_events(readiness, token, |_, file| Ok(callback((), file)))
144    }
145
146    fn register(
147        &mut self,
148        poll: &mut calloop::Poll,
149        token_factory: &mut calloop::TokenFactory,
150    ) -> calloop::Result<()> {
151        self.file.register(poll, token_factory)
152    }
153
154    fn reregister(
155        &mut self,
156        poll: &mut calloop::Poll,
157        token_factory: &mut calloop::TokenFactory,
158    ) -> calloop::Result<()> {
159        self.file.reregister(poll, token_factory)
160    }
161
162    fn unregister(&mut self, poll: &mut calloop::Poll) -> calloop::Result<()> {
163        self.file.unregister(poll)
164    }
165}