1use crate::protocol_helpers::prelude::*;
12use super::super::all_types::*;
13
14pub struct WlShmPool {
18 core: ObjectCore,
19 handler: HandlerHolder<dyn WlShmPoolHandler>,
20}
21
22struct DefaultHandler;
23
24impl WlShmPoolHandler for DefaultHandler { }
25
26impl ConcreteObject for WlShmPool {
27 const XML_VERSION: u32 = 2;
28 const INTERFACE: ObjectInterface = ObjectInterface::WlShmPool;
29 const INTERFACE_NAME: &str = "wl_shm_pool";
30}
31
32impl WlShmPool {
33 pub fn set_handler(&self, handler: impl WlShmPoolHandler) {
35 self.set_boxed_handler(Box::new(handler));
36 }
37
38 pub fn set_boxed_handler(&self, handler: Box<dyn WlShmPoolHandler>) {
40 if self.core.state.destroyed.get() {
41 return;
42 }
43 self.handler.set(Some(handler));
44 }
45}
46
47impl Debug for WlShmPool {
48 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
49 f.debug_struct("WlShmPool")
50 .field("server_obj_id", &self.core.server_obj_id.get())
51 .field("client_id", &self.core.client_id.get())
52 .field("client_obj_id", &self.core.client_obj_id.get())
53 .finish()
54 }
55}
56
57impl WlShmPool {
58 pub const MSG__CREATE_BUFFER__SINCE: u32 = 1;
60
61 #[inline]
84 pub fn try_send_create_buffer(
85 &self,
86 id: &Rc<WlBuffer>,
87 offset: i32,
88 width: i32,
89 height: i32,
90 stride: i32,
91 format: WlShmFormat,
92 ) -> Result<(), ObjectError> {
93 let (
94 arg0,
95 arg1,
96 arg2,
97 arg3,
98 arg4,
99 arg5,
100 ) = (
101 id,
102 offset,
103 width,
104 height,
105 stride,
106 format,
107 );
108 let arg0_obj = arg0;
109 let arg0 = arg0_obj.core();
110 let core = self.core();
111 let Some(id) = core.server_obj_id.get() else {
112 return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
113 };
114 arg0.generate_server_id(arg0_obj.clone())
115 .map_err(|e| ObjectError(ObjectErrorKind::GenerateServerId("id", e)))?;
116 let arg0_id = arg0.server_obj_id.get().unwrap_or(0);
117 #[cfg(feature = "logging")]
118 if self.core.state.log {
119 #[cold]
120 fn log(state: &State, id: u32, arg0: u32, arg1: i32, arg2: i32, arg3: i32, arg4: i32, arg5: WlShmFormat) {
121 let (millis, micros) = time_since_epoch();
122 let prefix = &state.log_prefix;
123 let args = format_args!("[{millis:7}.{micros:03}] {prefix}server <= wl_shm_pool#{}.create_buffer(id: wl_buffer#{}, offset: {}, width: {}, height: {}, stride: {}, format: {:?})\n", id, arg0, arg1, arg2, arg3, arg4, arg5);
124 state.log(args);
125 }
126 log(&self.core.state, id, arg0_id, arg1, arg2, arg3, arg4, arg5);
127 }
128 let Some(endpoint) = &self.core.state.server else {
129 return Ok(());
130 };
131 if !endpoint.flush_queued.replace(true) {
132 self.core.state.add_flushable_endpoint(endpoint, None);
133 }
134 let mut outgoing_ref = endpoint.outgoing.borrow_mut();
135 let outgoing = &mut *outgoing_ref;
136 let mut fmt = outgoing.formatter();
137 fmt.words([
138 id,
139 0,
140 arg0_id,
141 arg1 as u32,
142 arg2 as u32,
143 arg3 as u32,
144 arg4 as u32,
145 arg5.0,
146 ]);
147 Ok(())
148 }
149
150 #[inline]
173 pub fn send_create_buffer(
174 &self,
175 id: &Rc<WlBuffer>,
176 offset: i32,
177 width: i32,
178 height: i32,
179 stride: i32,
180 format: WlShmFormat,
181 ) {
182 let res = self.try_send_create_buffer(
183 id,
184 offset,
185 width,
186 height,
187 stride,
188 format,
189 );
190 if let Err(e) = res {
191 log_send("wl_shm_pool.create_buffer", &e);
192 }
193 }
194
195 #[inline]
217 pub fn new_try_send_create_buffer(
218 &self,
219 offset: i32,
220 width: i32,
221 height: i32,
222 stride: i32,
223 format: WlShmFormat,
224 ) -> Result<Rc<WlBuffer>, ObjectError> {
225 let id = self.core.create_child();
226 self.try_send_create_buffer(
227 &id,
228 offset,
229 width,
230 height,
231 stride,
232 format,
233 )?;
234 Ok(id)
235 }
236
237 #[inline]
259 pub fn new_send_create_buffer(
260 &self,
261 offset: i32,
262 width: i32,
263 height: i32,
264 stride: i32,
265 format: WlShmFormat,
266 ) -> Rc<WlBuffer> {
267 let id = self.core.create_child();
268 self.send_create_buffer(
269 &id,
270 offset,
271 width,
272 height,
273 stride,
274 format,
275 );
276 id
277 }
278
279 pub const MSG__DESTROY__SINCE: u32 = 1;
281
282 #[inline]
290 pub fn try_send_destroy(
291 &self,
292 ) -> Result<(), ObjectError> {
293 let core = self.core();
294 let Some(id) = core.server_obj_id.get() else {
295 return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
296 };
297 #[cfg(feature = "logging")]
298 if self.core.state.log {
299 #[cold]
300 fn log(state: &State, id: u32) {
301 let (millis, micros) = time_since_epoch();
302 let prefix = &state.log_prefix;
303 let args = format_args!("[{millis:7}.{micros:03}] {prefix}server <= wl_shm_pool#{}.destroy()\n", id);
304 state.log(args);
305 }
306 log(&self.core.state, id);
307 }
308 let Some(endpoint) = &self.core.state.server else {
309 return Ok(());
310 };
311 if !endpoint.flush_queued.replace(true) {
312 self.core.state.add_flushable_endpoint(endpoint, None);
313 }
314 let mut outgoing_ref = endpoint.outgoing.borrow_mut();
315 let outgoing = &mut *outgoing_ref;
316 let mut fmt = outgoing.formatter();
317 fmt.words([
318 id,
319 1,
320 ]);
321 self.core.handle_server_destroy();
322 Ok(())
323 }
324
325 #[inline]
333 pub fn send_destroy(
334 &self,
335 ) {
336 let res = self.try_send_destroy(
337 );
338 if let Err(e) = res {
339 log_send("wl_shm_pool.destroy", &e);
340 }
341 }
342
343 pub const MSG__RESIZE__SINCE: u32 = 1;
345
346 #[inline]
363 pub fn try_send_resize(
364 &self,
365 size: i32,
366 ) -> Result<(), ObjectError> {
367 let (
368 arg0,
369 ) = (
370 size,
371 );
372 let core = self.core();
373 let Some(id) = core.server_obj_id.get() else {
374 return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
375 };
376 #[cfg(feature = "logging")]
377 if self.core.state.log {
378 #[cold]
379 fn log(state: &State, id: u32, arg0: i32) {
380 let (millis, micros) = time_since_epoch();
381 let prefix = &state.log_prefix;
382 let args = format_args!("[{millis:7}.{micros:03}] {prefix}server <= wl_shm_pool#{}.resize(size: {})\n", id, arg0);
383 state.log(args);
384 }
385 log(&self.core.state, id, arg0);
386 }
387 let Some(endpoint) = &self.core.state.server else {
388 return Ok(());
389 };
390 if !endpoint.flush_queued.replace(true) {
391 self.core.state.add_flushable_endpoint(endpoint, None);
392 }
393 let mut outgoing_ref = endpoint.outgoing.borrow_mut();
394 let outgoing = &mut *outgoing_ref;
395 let mut fmt = outgoing.formatter();
396 fmt.words([
397 id,
398 2,
399 arg0 as u32,
400 ]);
401 Ok(())
402 }
403
404 #[inline]
421 pub fn send_resize(
422 &self,
423 size: i32,
424 ) {
425 let res = self.try_send_resize(
426 size,
427 );
428 if let Err(e) = res {
429 log_send("wl_shm_pool.resize", &e);
430 }
431 }
432}
433
434pub trait WlShmPoolHandler: Any {
436 #[inline]
440 fn delete_id(&mut self, slf: &Rc<WlShmPool>) {
441 slf.core.delete_id();
442 }
443
444 #[inline]
467 fn handle_create_buffer(
468 &mut self,
469 slf: &Rc<WlShmPool>,
470 id: &Rc<WlBuffer>,
471 offset: i32,
472 width: i32,
473 height: i32,
474 stride: i32,
475 format: WlShmFormat,
476 ) {
477 if !slf.core.forward_to_server.get() {
478 return;
479 }
480 let res = slf.try_send_create_buffer(
481 id,
482 offset,
483 width,
484 height,
485 stride,
486 format,
487 );
488 if let Err(e) = res {
489 log_forward("wl_shm_pool.create_buffer", &e);
490 }
491 }
492
493 #[inline]
501 fn handle_destroy(
502 &mut self,
503 slf: &Rc<WlShmPool>,
504 ) {
505 if !slf.core.forward_to_server.get() {
506 return;
507 }
508 let res = slf.try_send_destroy(
509 );
510 if let Err(e) = res {
511 log_forward("wl_shm_pool.destroy", &e);
512 }
513 }
514
515 #[inline]
532 fn handle_resize(
533 &mut self,
534 slf: &Rc<WlShmPool>,
535 size: i32,
536 ) {
537 if !slf.core.forward_to_server.get() {
538 return;
539 }
540 let res = slf.try_send_resize(
541 size,
542 );
543 if let Err(e) = res {
544 log_forward("wl_shm_pool.resize", &e);
545 }
546 }
547}
548
549impl ObjectPrivate for WlShmPool {
550 fn new(state: &Rc<State>, version: u32) -> Rc<Self> {
551 Rc::<Self>::new_cyclic(|slf| Self {
552 core: ObjectCore::new(state, slf.clone(), ObjectInterface::WlShmPool, version),
553 handler: Default::default(),
554 })
555 }
556
557 fn delete_id(self: Rc<Self>) -> Result<(), (ObjectError, Rc<dyn Object>)> {
558 let Some(mut handler) = self.handler.try_borrow_mut() else {
559 return Err((ObjectError(ObjectErrorKind::HandlerBorrowed), self));
560 };
561 if let Some(handler) = &mut *handler {
562 handler.delete_id(&self);
563 } else {
564 self.core.delete_id();
565 }
566 Ok(())
567 }
568
569 fn handle_request(self: Rc<Self>, client: &Rc<Client>, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
570 let Some(mut handler) = self.handler.try_borrow_mut() else {
571 return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
572 };
573 let handler = &mut *handler;
574 match msg[1] & 0xffff {
575 0 => {
576 let [
577 arg0,
578 arg1,
579 arg2,
580 arg3,
581 arg4,
582 arg5,
583 ] = msg[2..] else {
584 return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 32)));
585 };
586 let arg1 = arg1 as i32;
587 let arg2 = arg2 as i32;
588 let arg3 = arg3 as i32;
589 let arg4 = arg4 as i32;
590 let arg5 = WlShmFormat(arg5);
591 #[cfg(feature = "logging")]
592 if self.core.state.log {
593 #[cold]
594 fn log(state: &State, client_id: u64, id: u32, arg0: u32, arg1: i32, arg2: i32, arg3: i32, arg4: i32, arg5: WlShmFormat) {
595 let (millis, micros) = time_since_epoch();
596 let prefix = &state.log_prefix;
597 let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_shm_pool#{}.create_buffer(id: wl_buffer#{}, offset: {}, width: {}, height: {}, stride: {}, format: {:?})\n", client_id, id, arg0, arg1, arg2, arg3, arg4, arg5);
598 state.log(args);
599 }
600 log(&self.core.state, client.endpoint.id, msg[0], arg0, arg1, arg2, arg3, arg4, arg5);
601 }
602 let arg0_id = arg0;
603 let arg0 = WlBuffer::new(&self.core.state, self.core.version);
604 arg0.core().set_client_id(client, arg0_id, arg0.clone())
605 .map_err(|e| ObjectError(ObjectErrorKind::SetClientId(arg0_id, "id", e)))?;
606 let arg0 = &arg0;
607 if let Some(handler) = handler {
608 (**handler).handle_create_buffer(&self, arg0, arg1, arg2, arg3, arg4, arg5);
609 } else {
610 DefaultHandler.handle_create_buffer(&self, arg0, arg1, arg2, arg3, arg4, arg5);
611 }
612 }
613 1 => {
614 if msg.len() != 2 {
615 return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 8)));
616 }
617 #[cfg(feature = "logging")]
618 if self.core.state.log {
619 #[cold]
620 fn log(state: &State, client_id: u64, id: u32) {
621 let (millis, micros) = time_since_epoch();
622 let prefix = &state.log_prefix;
623 let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_shm_pool#{}.destroy()\n", client_id, id);
624 state.log(args);
625 }
626 log(&self.core.state, client.endpoint.id, msg[0]);
627 }
628 self.core.handle_client_destroy();
629 if let Some(handler) = handler {
630 (**handler).handle_destroy(&self);
631 } else {
632 DefaultHandler.handle_destroy(&self);
633 }
634 }
635 2 => {
636 let [
637 arg0,
638 ] = msg[2..] else {
639 return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
640 };
641 let arg0 = arg0 as i32;
642 #[cfg(feature = "logging")]
643 if self.core.state.log {
644 #[cold]
645 fn log(state: &State, client_id: u64, id: u32, arg0: i32) {
646 let (millis, micros) = time_since_epoch();
647 let prefix = &state.log_prefix;
648 let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_shm_pool#{}.resize(size: {})\n", client_id, id, arg0);
649 state.log(args);
650 }
651 log(&self.core.state, client.endpoint.id, msg[0], arg0);
652 }
653 if let Some(handler) = handler {
654 (**handler).handle_resize(&self, arg0);
655 } else {
656 DefaultHandler.handle_resize(&self, arg0);
657 }
658 }
659 n => {
660 let _ = client;
661 let _ = msg;
662 let _ = fds;
663 let _ = handler;
664 return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
665 }
666 }
667 Ok(())
668 }
669
670 fn handle_event(self: Rc<Self>, server: &Endpoint, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
671 let Some(mut handler) = self.handler.try_borrow_mut() else {
672 return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
673 };
674 let handler = &mut *handler;
675 match msg[1] & 0xffff {
676 n => {
677 let _ = server;
678 let _ = msg;
679 let _ = fds;
680 let _ = handler;
681 return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
682 }
683 }
684 }
685
686 fn get_request_name(&self, id: u32) -> Option<&'static str> {
687 let name = match id {
688 0 => "create_buffer",
689 1 => "destroy",
690 2 => "resize",
691 _ => return None,
692 };
693 Some(name)
694 }
695
696 fn get_event_name(&self, id: u32) -> Option<&'static str> {
697 let _ = id;
698 None
699 }
700}
701
702impl Object for WlShmPool {
703 fn core(&self) -> &ObjectCore {
704 &self.core
705 }
706
707 fn unset_handler(&self) {
708 self.handler.set(None);
709 }
710
711 fn get_handler_any_ref(&self) -> Result<HandlerRef<'_, dyn Any>, HandlerAccessError> {
712 let borrowed = self.handler.try_borrow().ok_or(HandlerAccessError::AlreadyBorrowed)?;
713 if borrowed.is_none() {
714 return Err(HandlerAccessError::NoHandler);
715 }
716 Ok(HandlerRef::map(borrowed, |handler| &**handler.as_ref().unwrap() as &dyn Any))
717 }
718
719 fn get_handler_any_mut(&self) -> Result<HandlerMut<'_, dyn Any>, HandlerAccessError> {
720 let borrowed = self.handler.try_borrow_mut().ok_or(HandlerAccessError::AlreadyBorrowed)?;
721 if borrowed.is_none() {
722 return Err(HandlerAccessError::NoHandler);
723 }
724 Ok(HandlerMut::map(borrowed, |handler| &mut **handler.as_mut().unwrap() as &mut dyn Any))
725 }
726}
727