1use std::{fmt::Debug, path::Path, ops::{Deref, DerefMut}, borrow::Cow, mem::size_of, num::NonZeroU32};
2
3use crate::{prelude::*};
4use ahash::{HashMap, HashMapExt};
5use syslib::{Socket, File, FileDescriptor};
6
7#[derive(Debug)]
8pub struct WlError<'a> {
9 pub object: Id,
10 pub error: u32,
11 pub description: Cow<'a, str>
12}
13impl<'a> WlError<'a> {
14 pub const CORRUPT: Self = Self {
15 object: Id::DISPLAY,
16 error: 1,
17 description: Cow::Borrowed("Protocol violation or malformed request.")
18 };
19 pub const NO_OBJECT: Self = Self {
20 object: Id::DISPLAY,
21 error: 0,
22 description: Cow::Borrowed("No object with that ID.")
23 };
24 pub const UNSUPPORTED_VERSION: Self = Self {
25 object: Id::DISPLAY,
26 error: 1,
27 description: Cow::Borrowed("The requested version of an interface is unsupported.")
28 };
29 pub const INVALID_OPCODE: Self = Self {
30 object: Id::DISPLAY,
31 error: 1,
32 description: Cow::Borrowed("Request contains an invalid opcode.")
33 };
34 pub const NO_GLOBAL: Self = Self {
35 object: Id::DISPLAY,
36 error: 1,
37 description: Cow::Borrowed("No global with that name.")
38 };
39 pub const UTF_8: Self = Self {
40 object: Id::DISPLAY,
41 error: 1,
42 description: Cow::Borrowed("Strings must be valid UTF-8.")
43 };
44 pub const NON_NULLABLE: Self = Self {
45 object: Id::DISPLAY,
46 error: 1,
47 description: Cow::Borrowed("Argument is not nullable.")
48 };
49 pub const NO_FD: Self = Self {
50 object: Id::DISPLAY,
51 error: 1,
52 description: Cow::Borrowed("Expected a file descriptor but none were received.")
53 };
54 pub const OOM: Self = Self {
55 object: Id::DISPLAY,
56 error: 2,
57 description: Cow::Borrowed("The compositor is out of memory.")
58 };
59 pub const INTERNAL: Self = Self {
60 object: Id::DISPLAY,
61 error: 3,
62 description: Cow::Borrowed("Internal compositor state is corrupted.")
63 };
64}
65
66#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
67#[repr(transparent)]
68pub struct Id(NonZeroU32);
69impl Id {
70 pub const DISPLAY: Self = Self(unsafe { NonZeroU32::new_unchecked(1) });
72 pub const fn new(value: u32) -> Self {
77 let Some(value) = NonZeroU32::new(value) else {
78 panic!()
79 };
80 Self(value)
81 }
82}
83impl From<NonZeroU32> for Id {
84 fn from(id: NonZeroU32) -> Self {
85 Self(id)
86 }
87}
88impl Into<u32> for Id {
89 fn into(self) -> u32 {
90 self.0.into()
91 }
92}
93#[derive(Debug)]
94pub struct NewId {
95 id: Id,
96 version: u32,
97 interface: String
98}
99impl NewId {
100 #[inline]
101 pub fn id(&self) -> Id {
102 self.id
103 }
104 #[inline]
105 pub fn version(&self) -> u32 {
106 self.version
107 }
108 #[inline]
109 pub fn interface(&self) -> &str {
110 &self.interface
111 }
112}
113#[repr(transparent)]
115pub struct Fixed(u32);
116impl Fixed {
117 #[inline]
118 fn from_raw(raw: u32) -> Self {
119 Self(raw)
120 }
121}
122
123#[derive(Debug)]
124pub struct Message {
125 pub object: Id,
126 pub opcode: u16,
127 pub size: u16
128}
129#[must_use]
131#[derive(Debug)]
132pub struct CommitKey(usize);
133
134pub trait EventSource<T> {
135 fn fd(&self) -> Fd<'static>;
136 fn destroy(&mut self, _event_loop: &mut EventLoop<T>) {}
137 fn input(&mut self, event_loop: &mut EventLoop<T>) -> crate::Result<()>;
138}
139pub struct EventLoop<T> {
140 epoll: File,
141 sources: HashMap<u32, Option<Box<dyn EventSource<T>>>>,
142 pub state: T
143}
144impl<T> EventLoop<T> {
145 pub fn new(state: T) -> crate::Result<Self> {
146 Ok(Self {
147 epoll: syslib::epoll_create(syslib::epoll::Flags::CLOSE_ON_EXEC)?,
148 sources: HashMap::new(),
149 state
150 })
151 }
152 pub fn add(&mut self, event_source: Box<dyn EventSource<T>>) -> crate::Result<()> {
153 use syslib::epoll;
154 let fd = event_source.fd();
155 let event = epoll::Event {
156 events: epoll::Events::INPUT | epoll::Events::ERROR | epoll::Events::HANG_UP,
157 data: epoll::Data { fd }
158 };
159 syslib::epoll_ctl(&self.epoll, &fd, epoll::Cntl::Add(event))?;
160 self.sources.insert(fd.raw(), Some(event_source));
161 Ok(())
162 }
163 pub fn wait(&mut self, timeout: u32) -> crate::Result<()> {
164 use syslib::epoll;
165 let mut events: [MaybeUninit<epoll::Event>; 32] = std::array::from_fn(|_| std::mem::MaybeUninit::uninit());
166 let events = syslib::epoll_wait(&self.epoll, &mut events, timeout)?;
167 for event in events {
168 let fd = unsafe { event.data.fd };
169 let mut had_error = false;
170 if event.events.any(epoll::Events::INPUT) {
171 let mut source = self.sources.get_mut(&fd.raw()).unwrap().take();
173 if let Err(err) = source.as_mut().unwrap().input(self) {
174 #[cfg(debug_assertions)]
175 eprintln!("Dropping event {:?}: {:?}", fd, err);
176 had_error = true;
177 }
178 let leased_source = self.sources.get_mut(&fd.raw())
179 .expect("An event source erroneously removed it's own entry.");
180 std::mem::swap(&mut source, leased_source)
182 }
183 if event.events.any(epoll::Events::ERROR | epoll::Events::HANG_UP) || had_error {
184 syslib::epoll_ctl(&self.epoll, &fd, epoll::Cntl::Delete)?;
185 let source = self.sources.remove(&fd.raw());
186 source.unwrap().unwrap().destroy(self);
187 }
188 }
189 Ok(())
190 }
191}
192impl<T> Deref for EventLoop<T> {
193 type Target = T;
194 fn deref(&self) -> &Self::Target {
195 &self.state
196 }
197}
198impl<T> DerefMut for EventLoop<T> {
199 fn deref_mut(&mut self) -> &mut Self::Target {
200 &mut self.state
201 }
202}
203
204pub struct Server {
205 pub(crate) socket: Socket
206}
207impl Server {
208 pub fn listen<P: AsRef<Path>>(path: P) -> crate::Result<Self> {
209 use std::os::unix::prelude::OsStrExt;
210 use syslib::sock::*;
211 let socket = syslib::socket(Domain::UNIX, Type::STREAM | TypeFlags::CLOSE_ON_EXEC, Protocol::UNSPECIFIED)?;
212 let address = UnixAddress::new(path.as_ref().as_os_str().as_bytes()).map_err(|_| Error::InvalidSocketPath)?;
213 syslib::bind(&socket, address.address())?;
214 syslib::listen(&socket, syslib::sock::MAX_CONNECTIONS)?;
215
216 Ok(Self {
217 socket
218 })
219 }
220}
221
222pub struct Stream {
223 pub(crate) socket: Socket,
224 rx_msg: RingBuffer<u32>,
225 tx_msg: Vec<u32>,
226 rx_fd: RingBuffer<File>,
227 tx_fd: RingBuffer<Fd<'static>>,
228}
229impl Stream {
230 pub fn connect<P: AsRef<Path>>(path: P) -> crate::Result<Self> {
234 use std::os::unix::prelude::OsStrExt;
235 use syslib::sock::*;
236 let socket = syslib::socket(Domain::UNIX, Type::STREAM | TypeFlags::CLOSE_ON_EXEC, Protocol::UNSPECIFIED)?;
237 let address = UnixAddress::new(path.as_ref().as_os_str().as_bytes()).map_err(|_| Error::InvalidSocketPath)?;
238 syslib::connect(&socket, address.address())?;
239
240 Self::new(socket)
241 }
242 pub(crate) fn new(socket: Socket) -> crate::Result<Self> {
243 let flags: syslib::open::Flags = syslib::fcntl(&socket, syslib::Fcntl::GetFd)?.try_into()?;
244 syslib::fcntl(&socket, syslib::Fcntl::SetFd(flags | syslib::open::Flags::CLOSE_ON_EXEC))?;
245 Ok(Self {
246 socket,
247 rx_msg: RingBuffer::new(1024),
248 tx_msg: Vec::with_capacity(1024),
249 rx_fd: RingBuffer::new(8),
250 tx_fd: RingBuffer::new(8)
251 })
252 }
253 pub fn message(&mut self) -> Option<Result<Message, WlError<'static>>> {
254 let req = self.rx_msg.get(1)?;
255 let size = ((req & 0xFFFF_0000) >> 16) as u16;
256 if size < 8 {
257 return Some(Err(WlError::CORRUPT))
258 }
259 if self.rx_msg.len() < (size as usize) / size_of::<u32>() {
260 return None;
261 }
262 let opcode = (req & 0xFFFF) as u16;
263 let object = match NonZeroU32::new(self.rx_msg.pop().unwrap()).ok_or(WlError::NON_NULLABLE) {
264 Ok(object) => object,
265 Err(e) => return Some(Err(e))
266 };
267 let object = Id(object);
268 let _ = self.rx_msg.pop();
269 Some(Ok(Message { object, opcode, size }))
270 }
271 pub fn start_message(&mut self, id: Id, opcode: u16) -> CommitKey {
272 let key = CommitKey(self.tx_msg.len());
273 self.tx_msg.push(id.into());
274 self.tx_msg.push(opcode as u32);
275 key
276 }
277 pub fn commit(&mut self, key: CommitKey) -> Result<(), WlError<'static>> {
279 let len = self.tx_msg.len() - key.0;
280 let req = self.tx_msg.get_mut(key.0 + 1).expect("Invalid message commit key.");
281 *req = (*req & 0x0000_FFFF) | ((len as u32) << 18);
282 Ok(())
283 }
284 pub fn i32(&mut self) -> Result<i32, WlError<'static>> {
285 self.rx_msg.pop().map(|i| i as i32).ok_or(WlError::CORRUPT)
286 }
287 pub fn send_i32(&mut self, i32: i32) -> Result<(), WlError<'static>> {
288 self.tx_msg.push(i32 as u32);
289 Ok(())
290 }
291 pub fn u32(&mut self) -> Result<u32, WlError<'static>> {
292 self.rx_msg.pop().ok_or(WlError::CORRUPT)
293 }
294 pub fn send_u32(&mut self, u32: u32) -> Result<(), WlError<'static>> {
295 self.tx_msg.push(u32);
296 Ok(())
297 }
298 pub fn fixed(&mut self) -> Result<Fixed, WlError<'static>> {
299 self.rx_msg.pop().map(|i| Fixed::from_raw(i)).ok_or(WlError::CORRUPT)
300 }
301 pub fn send_fixed(&mut self, fixed: Fixed) -> Result<(), WlError<'static>> {
302 self.tx_msg.push(fixed.0);
303 Ok(())
304 }
305 #[inline]
306 pub fn string(&mut self) -> Result<Option<String>, WlError<'static>> {
307 let mut bytes = match self.bytes() {
308 Ok(bytes) => bytes,
309 Err(e) => return Err(e)
310 };
311 let Some(0) = bytes.pop() else {
313 return Err(WlError::CORRUPT)
314 };
315 if bytes.len() == 0 {
316 Ok(None)
317 } else {
318 String::from_utf8(bytes).map_err(|_| WlError::UTF_8).map(Some)
319 }
320 }
321 #[inline]
322 pub fn send_string(&mut self, string: Option<&str>) -> Result<(), WlError<'static>> {
323 let Some(string) = string else {
324 return self.send_u32(0)
325 };
326 let len: u32 = string.len().try_into().unwrap();
327 let len = (len + 4) & !3;
328 self.send_u32(len)?;
329 self.tx_msg.reserve(len as usize);
330 unsafe {
331 self.tx_msg.as_mut_ptr().add(self.tx_msg.len() + (len as usize / size_of::<u32>()) - 1).write(0);
332 (self.tx_msg.as_mut_ptr().add(self.tx_msg.len()) as *mut u8).copy_from(string.as_ptr(), string.len());
333 self.tx_msg.set_len(self.tx_msg.len() + (len as usize / size_of::<u32>()));
334 }
335 Ok(())
336 }
337 pub fn object(&mut self) -> Result<Option<Id>, WlError<'static>> {
338 self.rx_msg.pop().map(|i| NonZeroU32::new(i).map(Id)).ok_or(WlError::CORRUPT)
339 }
340 pub fn send_object(&mut self, object: Option<Id>) -> Result<(), WlError<'static>> {
341 if let Some(object) = object {
342 self.send_u32(object.into())
343 } else {
344 self.send_u32(0)
345 }
346 }
347 pub fn new_id(&mut self) -> Result<NewId, WlError<'static>> {
348 let interface = self.string()?.ok_or(WlError::NON_NULLABLE)?;
349 let version = self.u32()?;
350 let id = self.object()?.ok_or(WlError::NON_NULLABLE)?;
351 Ok(NewId { id, version, interface })
352 }
353 pub fn send_new_id(&mut self, new_id: &NewId) -> Result<(), WlError<'static>> {
354 self.send_string(Some(new_id.interface()))?;
355 self.send_u32(new_id.version())?;
356 self.send_u32(new_id.id().into())
357 }
358 pub fn bytes(&mut self) -> Result<Vec<u8>, WlError<'static>> {
359 let len = self.u32()?;
360 if len == 0 { return Ok(Vec::new()) }
361 let take_len = (len as usize >> 2) + (len & 0b11 != 0) as usize;
363 if self.rx_msg.len() < take_len {
364 return Err(WlError::CORRUPT)
365 }
366 let mut bytes: Vec<u8> = Vec::with_capacity(len as usize);
367 if self.rx_msg.front > self.rx_msg.back {
368 unsafe {
370 let src = self.rx_msg.data.as_ptr() as *const u8;
371 bytes.as_mut_ptr().copy_from_nonoverlapping(src.add(self.rx_msg.back * size_of::<u32>()), len as usize);
372 bytes.set_len(len as usize);
373 }
374 } else {
375 unsafe {
377 let src = self.rx_msg.data.as_ptr() as *const u8;
378 let part_len = self.rx_msg.data.len() * size_of::<u32>() - self.rx_msg.back * size_of::<u32>();
379 bytes.as_mut_ptr().copy_from_nonoverlapping(src.add(self.rx_msg.back * size_of::<u32>()), part_len);
380 bytes.as_mut_ptr().add(part_len).copy_from_nonoverlapping(src, self.rx_msg.front * size_of::<u32>());
381 bytes.set_len(len as usize);
382 }
383 }
384 self.rx_msg.back = (self.rx_msg.back + take_len) & (self.rx_msg.data.len() - 1);
385 Ok(bytes)
386 }
387 pub fn send_bytes(&mut self, bytes: &[u8]) -> Result<(), WlError<'static>> {
388 if bytes.len() == 0 {
389 return Ok(())
390 }
391 let len: u32 = bytes.len().try_into().unwrap();
392 let len = (len + 3) & !3;
393 self.send_u32(len)?;
394 self.tx_msg.reserve(len as usize);
395 unsafe {
396 self.tx_msg.as_mut_ptr().add(self.tx_msg.len() + (len as usize / size_of::<u32>()) - 1).write(0);
397 (self.tx_msg.as_mut_ptr().add(self.tx_msg.len()) as *mut u8).copy_from(bytes.as_ptr(), bytes.len());
398 self.tx_msg.set_len(self.tx_msg.len() + (len as usize / size_of::<u32>()));
399 }
400 Ok(())
401 }
402 pub fn file(&mut self) -> Result<File, WlError<'static>> {
403 self.rx_fd.pop().ok_or(WlError::CORRUPT)
404 }
405 pub fn send_file(&mut self, fd: Fd<'static>) -> Result<(), WlError<'static>> {
406 if let Some(_) = self.tx_fd.push(fd) {
407 Err(WlError::INTERNAL)
408 } else {
409 Ok(())
410 }
411 }
412
413 pub fn recvmsg(&mut self) -> crate::Result<bool> {
418 use syslib::*;
419 let t = (self.rx_msg.front + self.rx_msg.data.len() - 1) & (self.rx_msg.data.len() - 1);
420 if self.rx_msg.front == t {
421 return Ok(false)
422 }
423 let iov = unsafe {
424 if self.rx_msg.front > t {
425 [
426 IoVecMut::maybe_uninit(self.rx_msg.data.as_mut_ptr().add(self.rx_msg.front) as *mut u8, (self.rx_msg.data.len() - self.rx_msg.front) * size_of::<u32>()),
427 IoVecMut::maybe_uninit(self.rx_msg.data.as_mut_ptr() as *mut u8, t * size_of::<u32>())
428 ]
429 } else {
430 [
431 IoVecMut::maybe_uninit(self.rx_msg.data.as_mut_ptr().add(self.rx_msg.front) as *mut u8, (t - self.rx_msg.front) * size_of::<u32>()),
432 IoVecMut::maybe_uninit(std::ptr::null_mut(), 0)
433 ]
434 }
435 };
436 let mut ancillary = sock::Ancillary::<Fd, 8>::new();
437 let read = syslib::recvmsg(&self.socket, &iov, Some(&mut ancillary), syslib::sock::Flags::NONE)? / size_of::<u32>();
438 self.rx_msg.front = (self.rx_msg.front + read) & (self.rx_msg.data.len() - 1);
439 if ancillary.ty() == sock::AncillaryType::RIGHTS && ancillary.level() == sock::Level::SOCKET {
440 for fd in ancillary.items() {
441 self.rx_fd.push(unsafe { fd.assume_init().owned() });
443 }
444 }
445 Ok(read != 0)
446 }
447
448 pub fn sendmsg(&mut self) -> crate::Result<()> {
449 use syslib::*;
450 let iov = [
451 IoVec::new(unsafe { std::slice::from_raw_parts(self.tx_msg.as_ptr() as *const u8, self.tx_msg.len() * size_of::<u32>()) })
452 ];
453 let mut ancillary = sock::Ancillary::<Fd, 8>::new();
454 let mut count = 8;
455 loop {
456 if let Some(item) = self.tx_fd.pop() {
457 ancillary.add_item(item);
458 } else {
459 break
460 }
461 if count == 0 {
462 break
463 }
464 count -= 1
465 }
466 sendmsg(&self.socket, &iov, Some(&ancillary), sock::Flags::NONE)?;
467 self.tx_msg.clear();
468 Ok(())
469 }
470}
471
472use std::mem::MaybeUninit;
473pub struct RingBuffer<T> {
490 data: Box<[MaybeUninit<T>]>,
491 front: usize,
492 back: usize
493}
494impl<T> RingBuffer<T> {
495 pub fn new(capacity: usize) -> Self {
503 if !capacity.is_power_of_two() {
504 panic!("Cannot construct a RingBuffer with a length of {capacity} as it is not a power of 2.")
505 }
506 let data = unsafe {
507 let layout = std::alloc::Layout::array::<MaybeUninit<T>>(capacity).unwrap();
508 let data = std::alloc::alloc(layout) as *mut MaybeUninit<T>;
509 let slice = std::slice::from_raw_parts_mut(data, capacity);
510 Box::from_raw(slice)
511 };
512 Self {
513 data,
514 front: 0,
515 back: 0
516 }
517 }
518 pub fn iter(&self) -> RingBufferIter<'_, T> {
519 RingBufferIter { ring_buffer: self, index: 0 }
520 }
521 #[inline(always)]
522 fn increment(&self, value: usize) -> usize {
523 (value + 1) & (self.data.len() - 1)
524 }
525 pub fn push(&mut self, value: T) -> Option<T> {
527 let next = self.increment(self.front);
528 if next == self.back {
529 Some(value)
530 } else {
531 self.data[self.front] = MaybeUninit::new(value);
532 self.front = next;
533 None
534 }
535 }
536 pub fn pop(&mut self) -> Option<T> {
538 if self.front == self.back {
539 None
540 } else {
541 let index = self.back;
542 self.back = self.increment(self.back);
543 Some(unsafe { self.data[index].assume_init_read() })
544 }
545 }
546 pub fn clear(&mut self) {
548 for s in self {
550 drop(s)
551 }
552 }
553 pub fn get(&self, index: usize) -> Option<&T> {
555 let i = (self.back + index) & (self.data.len() - 1);
556 if index < self.len() {
557 Some(unsafe { self.data[i].assume_init_ref() })
558 } else {
559 None
560 }
561 }
562 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
564 let i = (self.back + index) & (self.data.len() - 1);
565 if index < self.len() {
566 Some(unsafe { self.data[i].assume_init_mut() })
567 } else {
568 None
569 }
570 }
571 pub fn get_linear(&self, index: usize) -> Option<&T> {
575 if (self.front > self.back && index >= self.back && index < self.front) || (self.front < self.back && (index >= self.back || index < self.front)) {
576 self.data.get(index).map(|t| unsafe { t.assume_init_ref()})
577 } else {
578 None
579 }
580 }
581 pub fn get_linear_mut(&mut self, index: usize) -> Option<&mut T> {
585 if (self.front > self.back && index >= self.back && index < self.front) || (self.front < self.back && (index >= self.back || index < self.front)) {
586 self.data.get_mut(index).map(|t| unsafe { t.assume_init_mut()})
587 } else {
588 None
589 }
590 }
591 pub fn front(&self) -> usize {
593 self.front
594 }
595 pub fn back(&self) -> usize {
597 self.back
598 }
599 pub fn len(&self) -> usize {
601 if self.front < self.back {
602 (self.front + self.data.len()) - self.back
603 } else {
604 self.front - self.back
605 }
606 }
607 pub fn free(&self) -> usize {
609 self.data.len() - (
610 if self.front < self.back {
611 (self.front + self.data.len()) - self.back
612 } else {
613 self.front - self.back
614 }
615 )
616 }
617 pub fn capacity(&self) -> usize {
619 self.data.len()
620 }
621 pub fn is_empty(&self) -> bool {
623 self.front == self.back
624 }
625 pub fn is_full(&self) -> bool {
627 self.front == self.back
628 }
629}
630impl<T> Drop for RingBuffer<T> {
631 fn drop(&mut self) {
632 for value in self {
633 std::mem::drop(value)
634 }
635 }
636}
637impl<T> Iterator for RingBuffer<T> {
638 type Item = T;
639 fn next(&mut self) -> Option<Self::Item> {
640 self.pop()
641 }
642}
643impl<T: Clone + Copy> Clone for RingBuffer<T> {
644 fn clone(&self) -> Self {
645 Self {
646 data: self.data.clone(),
647 front: self.front,
648 back: self.back
649 }
650 }
651}
652impl<T: Debug> Debug for RingBuffer<T> {
653 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
654 f.debug_list()
655 .entries(self.iter())
656 .finish()
657 }
658}
659
660pub struct RingBufferIter<'a, T> {
661 ring_buffer: &'a RingBuffer<T>,
662 index: usize
663}
664impl<'a, T> Iterator for RingBufferIter<'a, T> {
665 type Item = &'a T;
666 fn next(&mut self) -> Option<Self::Item> {
667 let index = self.index;
668 self.index += 1;
669 self.ring_buffer.get(index)
670 }
671}
672pub struct RingBufferIterMut<'a, T> {
673 ring_buffer: &'a mut RingBuffer<T>,
674 index: usize
675}
676impl<'a, T> Iterator for RingBufferIterMut<'a, T> {
677 type Item = &'a mut T;
678 fn next(&mut self) -> Option<Self::Item> {
679 let index = self.index;
680 self.index += 1;
681 self.ring_buffer.get_mut(index).map(|i| unsafe { &mut *(i as *mut T) })
682 }
683}