wl_proxy/protocols/wayland/
wl_shell.rs1use crate::protocol_helpers::prelude::*;
14use super::super::all_types::*;
15
16pub struct WlShell {
20 core: ObjectCore,
21 handler: HandlerHolder<dyn WlShellHandler>,
22}
23
24struct DefaultHandler;
25
26impl WlShellHandler for DefaultHandler { }
27
28impl ConcreteObject for WlShell {
29 const XML_VERSION: u32 = 1;
30 const INTERFACE: ObjectInterface = ObjectInterface::WlShell;
31 const INTERFACE_NAME: &str = "wl_shell";
32}
33
34impl WlShell {
35 pub fn set_handler(&self, handler: impl WlShellHandler) {
37 self.set_boxed_handler(Box::new(handler));
38 }
39
40 pub fn set_boxed_handler(&self, handler: Box<dyn WlShellHandler>) {
42 if self.core.state.destroyed.get() {
43 return;
44 }
45 self.handler.set(Some(handler));
46 }
47}
48
49impl Debug for WlShell {
50 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
51 f.debug_struct("WlShell")
52 .field("server_obj_id", &self.core.server_obj_id.get())
53 .field("client_id", &self.core.client_id.get())
54 .field("client_obj_id", &self.core.client_obj_id.get())
55 .finish()
56 }
57}
58
59impl WlShell {
60 pub const MSG__GET_SHELL_SURFACE__SINCE: u32 = 1;
62
63 #[inline]
76 pub fn try_send_get_shell_surface(
77 &self,
78 id: &Rc<WlShellSurface>,
79 surface: &Rc<WlSurface>,
80 ) -> Result<(), ObjectError> {
81 let (
82 arg0,
83 arg1,
84 ) = (
85 id,
86 surface,
87 );
88 let arg0_obj = arg0;
89 let arg0 = arg0_obj.core();
90 let arg1 = arg1.core();
91 let core = self.core();
92 let Some(id) = core.server_obj_id.get() else {
93 return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
94 };
95 let arg1_id = match arg1.server_obj_id.get() {
96 None => return Err(ObjectError(ObjectErrorKind::ArgNoServerId("surface"))),
97 Some(id) => id,
98 };
99 arg0.generate_server_id(arg0_obj.clone())
100 .map_err(|e| ObjectError(ObjectErrorKind::GenerateServerId("id", e)))?;
101 let arg0_id = arg0.server_obj_id.get().unwrap_or(0);
102 #[cfg(feature = "logging")]
103 if self.core.state.log {
104 #[cold]
105 fn log(state: &State, id: u32, arg0: u32, arg1: u32) {
106 let (millis, micros) = time_since_epoch();
107 let prefix = &state.log_prefix;
108 let args = format_args!("[{millis:7}.{micros:03}] {prefix}server <= wl_shell#{}.get_shell_surface(id: wl_shell_surface#{}, surface: wl_surface#{})\n", id, arg0, arg1);
109 state.log(args);
110 }
111 log(&self.core.state, id, arg0_id, arg1_id);
112 }
113 let Some(endpoint) = &self.core.state.server else {
114 return Ok(());
115 };
116 if !endpoint.flush_queued.replace(true) {
117 self.core.state.add_flushable_endpoint(endpoint, None);
118 }
119 let mut outgoing_ref = endpoint.outgoing.borrow_mut();
120 let outgoing = &mut *outgoing_ref;
121 let mut fmt = outgoing.formatter();
122 fmt.words([
123 id,
124 0,
125 arg0_id,
126 arg1_id,
127 ]);
128 Ok(())
129 }
130
131 #[inline]
144 pub fn send_get_shell_surface(
145 &self,
146 id: &Rc<WlShellSurface>,
147 surface: &Rc<WlSurface>,
148 ) {
149 let res = self.try_send_get_shell_surface(
150 id,
151 surface,
152 );
153 if let Err(e) = res {
154 log_send("wl_shell.get_shell_surface", &e);
155 }
156 }
157
158 #[inline]
170 pub fn new_try_send_get_shell_surface(
171 &self,
172 surface: &Rc<WlSurface>,
173 ) -> Result<Rc<WlShellSurface>, ObjectError> {
174 let id = self.core.create_child();
175 self.try_send_get_shell_surface(
176 &id,
177 surface,
178 )?;
179 Ok(id)
180 }
181
182 #[inline]
194 pub fn new_send_get_shell_surface(
195 &self,
196 surface: &Rc<WlSurface>,
197 ) -> Rc<WlShellSurface> {
198 let id = self.core.create_child();
199 self.send_get_shell_surface(
200 &id,
201 surface,
202 );
203 id
204 }
205}
206
207pub trait WlShellHandler: Any {
209 #[inline]
213 fn delete_id(&mut self, slf: &Rc<WlShell>) {
214 slf.core.delete_id();
215 }
216
217 #[inline]
233 fn handle_get_shell_surface(
234 &mut self,
235 slf: &Rc<WlShell>,
236 id: &Rc<WlShellSurface>,
237 surface: &Rc<WlSurface>,
238 ) {
239 if !slf.core.forward_to_server.get() {
240 return;
241 }
242 let res = slf.try_send_get_shell_surface(
243 id,
244 surface,
245 );
246 if let Err(e) = res {
247 log_forward("wl_shell.get_shell_surface", &e);
248 }
249 }
250}
251
252impl ObjectPrivate for WlShell {
253 fn new(state: &Rc<State>, version: u32) -> Rc<Self> {
254 Rc::<Self>::new_cyclic(|slf| Self {
255 core: ObjectCore::new(state, slf.clone(), ObjectInterface::WlShell, version),
256 handler: Default::default(),
257 })
258 }
259
260 fn delete_id(self: Rc<Self>) -> Result<(), (ObjectError, Rc<dyn Object>)> {
261 let Some(mut handler) = self.handler.try_borrow_mut() else {
262 return Err((ObjectError(ObjectErrorKind::HandlerBorrowed), self));
263 };
264 if let Some(handler) = &mut *handler {
265 handler.delete_id(&self);
266 } else {
267 self.core.delete_id();
268 }
269 Ok(())
270 }
271
272 fn handle_request(self: Rc<Self>, client: &Rc<Client>, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
273 let Some(mut handler) = self.handler.try_borrow_mut() else {
274 return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
275 };
276 let handler = &mut *handler;
277 match msg[1] & 0xffff {
278 0 => {
279 let [
280 arg0,
281 arg1,
282 ] = msg[2..] else {
283 return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 16)));
284 };
285 #[cfg(feature = "logging")]
286 if self.core.state.log {
287 #[cold]
288 fn log(state: &State, client_id: u64, id: u32, arg0: u32, arg1: u32) {
289 let (millis, micros) = time_since_epoch();
290 let prefix = &state.log_prefix;
291 let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_shell#{}.get_shell_surface(id: wl_shell_surface#{}, surface: wl_surface#{})\n", client_id, id, arg0, arg1);
292 state.log(args);
293 }
294 log(&self.core.state, client.endpoint.id, msg[0], arg0, arg1);
295 }
296 let arg0_id = arg0;
297 let arg0 = WlShellSurface::new(&self.core.state, self.core.version);
298 arg0.core().set_client_id(client, arg0_id, arg0.clone())
299 .map_err(|e| ObjectError(ObjectErrorKind::SetClientId(arg0_id, "id", e)))?;
300 let arg1_id = arg1;
301 let Some(arg1) = client.endpoint.lookup(arg1_id) else {
302 return Err(ObjectError(ObjectErrorKind::NoClientObject(client.endpoint.id, arg1_id)));
303 };
304 let Ok(arg1) = (arg1 as Rc<dyn Any>).downcast::<WlSurface>() else {
305 let o = client.endpoint.lookup(arg1_id).unwrap();
306 return Err(ObjectError(ObjectErrorKind::WrongObjectType("surface", o.core().interface, ObjectInterface::WlSurface)));
307 };
308 let arg0 = &arg0;
309 let arg1 = &arg1;
310 if let Some(handler) = handler {
311 (**handler).handle_get_shell_surface(&self, arg0, arg1);
312 } else {
313 DefaultHandler.handle_get_shell_surface(&self, arg0, arg1);
314 }
315 }
316 n => {
317 let _ = client;
318 let _ = msg;
319 let _ = fds;
320 let _ = handler;
321 return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
322 }
323 }
324 Ok(())
325 }
326
327 fn handle_event(self: Rc<Self>, server: &Endpoint, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
328 let Some(mut handler) = self.handler.try_borrow_mut() else {
329 return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
330 };
331 let handler = &mut *handler;
332 match msg[1] & 0xffff {
333 n => {
334 let _ = server;
335 let _ = msg;
336 let _ = fds;
337 let _ = handler;
338 return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
339 }
340 }
341 }
342
343 fn get_request_name(&self, id: u32) -> Option<&'static str> {
344 let name = match id {
345 0 => "get_shell_surface",
346 _ => return None,
347 };
348 Some(name)
349 }
350
351 fn get_event_name(&self, id: u32) -> Option<&'static str> {
352 let _ = id;
353 None
354 }
355}
356
357impl Object for WlShell {
358 fn core(&self) -> &ObjectCore {
359 &self.core
360 }
361
362 fn unset_handler(&self) {
363 self.handler.set(None);
364 }
365
366 fn get_handler_any_ref(&self) -> Result<HandlerRef<'_, dyn Any>, HandlerAccessError> {
367 let borrowed = self.handler.try_borrow().ok_or(HandlerAccessError::AlreadyBorrowed)?;
368 if borrowed.is_none() {
369 return Err(HandlerAccessError::NoHandler);
370 }
371 Ok(HandlerRef::map(borrowed, |handler| &**handler.as_ref().unwrap() as &dyn Any))
372 }
373
374 fn get_handler_any_mut(&self) -> Result<HandlerMut<'_, dyn Any>, HandlerAccessError> {
375 let borrowed = self.handler.try_borrow_mut().ok_or(HandlerAccessError::AlreadyBorrowed)?;
376 if borrowed.is_none() {
377 return Err(HandlerAccessError::NoHandler);
378 }
379 Ok(HandlerMut::map(borrowed, |handler| &mut **handler.as_mut().unwrap() as &mut dyn Any))
380 }
381}
382
383impl WlShell {
384 pub const ENM__ERROR_ROLE__SINCE: u32 = 1;
386}
387
388#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
389pub struct WlShellError(pub u32);
390
391impl WlShellError {
392 pub const ROLE: Self = Self(0);
394}
395
396impl Debug for WlShellError {
397 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
398 let name = match *self {
399 Self::ROLE => "ROLE",
400 _ => return Debug::fmt(&self.0, f),
401 };
402 f.write_str(name)
403 }
404}