wl_proxy/protocols/wayland/wl_pointer.rs
1//! pointer input device
2//!
3//! The wl_pointer interface represents one or more input devices,
4//! such as mice, which control the pointer location and pointer_focus
5//! of a seat.
6//!
7//! The wl_pointer interface generates motion, enter and leave
8//! events for the surfaces that the pointer is located over,
9//! and button and axis events for button presses, button releases
10//! and scrolling.
11
12use crate::protocol_helpers::prelude::*;
13use super::super::all_types::*;
14
15/// A wl_pointer object.
16///
17/// See the documentation of [the module][self] for the interface description.
18pub struct WlPointer {
19 core: ObjectCore,
20 handler: HandlerHolder<dyn WlPointerHandler>,
21}
22
23struct DefaultHandler;
24
25impl WlPointerHandler for DefaultHandler { }
26
27impl ConcreteObject for WlPointer {
28 const XML_VERSION: u32 = 10;
29 const INTERFACE: ObjectInterface = ObjectInterface::WlPointer;
30 const INTERFACE_NAME: &str = "wl_pointer";
31}
32
33impl WlPointer {
34 /// Sets a new handler.
35 pub fn set_handler(&self, handler: impl WlPointerHandler) {
36 self.set_boxed_handler(Box::new(handler));
37 }
38
39 /// Sets a new, already boxed handler.
40 pub fn set_boxed_handler(&self, handler: Box<dyn WlPointerHandler>) {
41 if self.core.state.destroyed.get() {
42 return;
43 }
44 self.handler.set(Some(handler));
45 }
46}
47
48impl Debug for WlPointer {
49 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
50 f.debug_struct("WlPointer")
51 .field("server_obj_id", &self.core.server_obj_id.get())
52 .field("client_id", &self.core.client_id.get())
53 .field("client_obj_id", &self.core.client_obj_id.get())
54 .finish()
55 }
56}
57
58impl WlPointer {
59 /// Since when the set_cursor message is available.
60 pub const MSG__SET_CURSOR__SINCE: u32 = 1;
61
62 /// set the pointer surface
63 ///
64 /// Set the pointer surface, i.e., the surface that contains the
65 /// pointer image (cursor). This request gives the surface the role
66 /// of a cursor. If the surface already has another role, it raises
67 /// a protocol error.
68 ///
69 /// The cursor actually changes only if the pointer
70 /// focus for this device is one of the requesting client's surfaces
71 /// or the surface parameter is the current pointer surface. If
72 /// there was a previous surface set with this request it is
73 /// replaced. If surface is NULL, the pointer image is hidden.
74 ///
75 /// The parameters hotspot_x and hotspot_y define the position of
76 /// the pointer surface relative to the pointer location. Its
77 /// top-left corner is always at (x, y) - (hotspot_x, hotspot_y),
78 /// where (x, y) are the coordinates of the pointer location, in
79 /// surface-local coordinates.
80 ///
81 /// On wl_surface.offset requests to the pointer surface, hotspot_x
82 /// and hotspot_y are decremented by the x and y parameters
83 /// passed to the request. The offset must be applied by
84 /// wl_surface.commit as usual.
85 ///
86 /// The hotspot can also be updated by passing the currently set
87 /// pointer surface to this request with new values for hotspot_x
88 /// and hotspot_y.
89 ///
90 /// The input region is ignored for wl_surfaces with the role of
91 /// a cursor. When the use as a cursor ends, the wl_surface is
92 /// unmapped.
93 ///
94 /// The serial parameter must match the latest wl_pointer.enter
95 /// serial number sent to the client. Otherwise the request will be
96 /// ignored.
97 ///
98 /// # Arguments
99 ///
100 /// - `serial`: serial number of the enter event
101 /// - `surface`: pointer surface
102 /// - `hotspot_x`: surface-local x coordinate
103 /// - `hotspot_y`: surface-local y coordinate
104 #[inline]
105 pub fn try_send_set_cursor(
106 &self,
107 serial: u32,
108 surface: Option<&Rc<WlSurface>>,
109 hotspot_x: i32,
110 hotspot_y: i32,
111 ) -> Result<(), ObjectError> {
112 let (
113 arg0,
114 arg1,
115 arg2,
116 arg3,
117 ) = (
118 serial,
119 surface,
120 hotspot_x,
121 hotspot_y,
122 );
123 let arg1 = arg1.map(|a| a.core());
124 let core = self.core();
125 let Some(id) = core.server_obj_id.get() else {
126 return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
127 };
128 let arg1_id = match arg1 {
129 None => 0,
130 Some(arg1) => match arg1.server_obj_id.get() {
131 None => return Err(ObjectError(ObjectErrorKind::ArgNoServerId("surface"))),
132 Some(id) => id,
133 },
134 };
135 #[cfg(feature = "logging")]
136 if self.core.state.log {
137 #[cold]
138 fn log(state: &State, id: u32, arg0: u32, arg1: u32, arg2: i32, arg3: i32) {
139 let (millis, micros) = time_since_epoch();
140 let prefix = &state.log_prefix;
141 let args = format_args!("[{millis:7}.{micros:03}] {prefix}server <= wl_pointer#{}.set_cursor(serial: {}, surface: wl_surface#{}, hotspot_x: {}, hotspot_y: {})\n", id, arg0, arg1, arg2, arg3);
142 state.log(args);
143 }
144 log(&self.core.state, id, arg0, arg1_id, arg2, arg3);
145 }
146 let Some(endpoint) = &self.core.state.server else {
147 return Ok(());
148 };
149 if !endpoint.flush_queued.replace(true) {
150 self.core.state.add_flushable_endpoint(endpoint, None);
151 }
152 let mut outgoing_ref = endpoint.outgoing.borrow_mut();
153 let outgoing = &mut *outgoing_ref;
154 let mut fmt = outgoing.formatter();
155 fmt.words([
156 id,
157 0,
158 arg0,
159 arg1_id,
160 arg2 as u32,
161 arg3 as u32,
162 ]);
163 Ok(())
164 }
165
166 /// set the pointer surface
167 ///
168 /// Set the pointer surface, i.e., the surface that contains the
169 /// pointer image (cursor). This request gives the surface the role
170 /// of a cursor. If the surface already has another role, it raises
171 /// a protocol error.
172 ///
173 /// The cursor actually changes only if the pointer
174 /// focus for this device is one of the requesting client's surfaces
175 /// or the surface parameter is the current pointer surface. If
176 /// there was a previous surface set with this request it is
177 /// replaced. If surface is NULL, the pointer image is hidden.
178 ///
179 /// The parameters hotspot_x and hotspot_y define the position of
180 /// the pointer surface relative to the pointer location. Its
181 /// top-left corner is always at (x, y) - (hotspot_x, hotspot_y),
182 /// where (x, y) are the coordinates of the pointer location, in
183 /// surface-local coordinates.
184 ///
185 /// On wl_surface.offset requests to the pointer surface, hotspot_x
186 /// and hotspot_y are decremented by the x and y parameters
187 /// passed to the request. The offset must be applied by
188 /// wl_surface.commit as usual.
189 ///
190 /// The hotspot can also be updated by passing the currently set
191 /// pointer surface to this request with new values for hotspot_x
192 /// and hotspot_y.
193 ///
194 /// The input region is ignored for wl_surfaces with the role of
195 /// a cursor. When the use as a cursor ends, the wl_surface is
196 /// unmapped.
197 ///
198 /// The serial parameter must match the latest wl_pointer.enter
199 /// serial number sent to the client. Otherwise the request will be
200 /// ignored.
201 ///
202 /// # Arguments
203 ///
204 /// - `serial`: serial number of the enter event
205 /// - `surface`: pointer surface
206 /// - `hotspot_x`: surface-local x coordinate
207 /// - `hotspot_y`: surface-local y coordinate
208 #[inline]
209 pub fn send_set_cursor(
210 &self,
211 serial: u32,
212 surface: Option<&Rc<WlSurface>>,
213 hotspot_x: i32,
214 hotspot_y: i32,
215 ) {
216 let res = self.try_send_set_cursor(
217 serial,
218 surface,
219 hotspot_x,
220 hotspot_y,
221 );
222 if let Err(e) = res {
223 log_send("wl_pointer.set_cursor", &e);
224 }
225 }
226
227 /// Since when the enter message is available.
228 pub const MSG__ENTER__SINCE: u32 = 1;
229
230 /// enter event
231 ///
232 /// Notification that this seat's pointer is focused on a certain
233 /// surface.
234 ///
235 /// When a seat's focus enters a surface, the pointer image
236 /// is undefined and a client should respond to this event by setting
237 /// an appropriate pointer image with the set_cursor request.
238 ///
239 /// # Arguments
240 ///
241 /// - `serial`: serial number of the enter event
242 /// - `surface`: surface entered by the pointer
243 /// - `surface_x`: surface-local x coordinate
244 /// - `surface_y`: surface-local y coordinate
245 #[inline]
246 pub fn try_send_enter(
247 &self,
248 serial: u32,
249 surface: &Rc<WlSurface>,
250 surface_x: Fixed,
251 surface_y: Fixed,
252 ) -> Result<(), ObjectError> {
253 let (
254 arg0,
255 arg1,
256 arg2,
257 arg3,
258 ) = (
259 serial,
260 surface,
261 surface_x,
262 surface_y,
263 );
264 let arg1 = arg1.core();
265 let core = self.core();
266 let client_ref = core.client.borrow();
267 let Some(client) = &*client_ref else {
268 return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
269 };
270 let id = core.client_obj_id.get().unwrap_or(0);
271 if arg1.client_id.get() != Some(client.endpoint.id) {
272 return Err(ObjectError(ObjectErrorKind::ArgNoClientId("surface", client.endpoint.id)));
273 }
274 let arg1_id = arg1.client_obj_id.get().unwrap_or(0);
275 #[cfg(feature = "logging")]
276 if self.core.state.log {
277 #[cold]
278 fn log(state: &State, client_id: u64, id: u32, arg0: u32, arg1: u32, arg2: Fixed, arg3: Fixed) {
279 let (millis, micros) = time_since_epoch();
280 let prefix = &state.log_prefix;
281 let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_pointer#{}.enter(serial: {}, surface: wl_surface#{}, surface_x: {}, surface_y: {})\n", client_id, id, arg0, arg1, arg2, arg3);
282 state.log(args);
283 }
284 log(&self.core.state, client.endpoint.id, id, arg0, arg1_id, arg2, arg3);
285 }
286 let endpoint = &client.endpoint;
287 if !endpoint.flush_queued.replace(true) {
288 self.core.state.add_flushable_endpoint(endpoint, Some(client));
289 }
290 let mut outgoing_ref = endpoint.outgoing.borrow_mut();
291 let outgoing = &mut *outgoing_ref;
292 let mut fmt = outgoing.formatter();
293 fmt.words([
294 id,
295 0,
296 arg0,
297 arg1_id,
298 arg2.to_wire() as u32,
299 arg3.to_wire() as u32,
300 ]);
301 Ok(())
302 }
303
304 /// enter event
305 ///
306 /// Notification that this seat's pointer is focused on a certain
307 /// surface.
308 ///
309 /// When a seat's focus enters a surface, the pointer image
310 /// is undefined and a client should respond to this event by setting
311 /// an appropriate pointer image with the set_cursor request.
312 ///
313 /// # Arguments
314 ///
315 /// - `serial`: serial number of the enter event
316 /// - `surface`: surface entered by the pointer
317 /// - `surface_x`: surface-local x coordinate
318 /// - `surface_y`: surface-local y coordinate
319 #[inline]
320 pub fn send_enter(
321 &self,
322 serial: u32,
323 surface: &Rc<WlSurface>,
324 surface_x: Fixed,
325 surface_y: Fixed,
326 ) {
327 let res = self.try_send_enter(
328 serial,
329 surface,
330 surface_x,
331 surface_y,
332 );
333 if let Err(e) = res {
334 log_send("wl_pointer.enter", &e);
335 }
336 }
337
338 /// Since when the leave message is available.
339 pub const MSG__LEAVE__SINCE: u32 = 1;
340
341 /// leave event
342 ///
343 /// Notification that this seat's pointer is no longer focused on
344 /// a certain surface.
345 ///
346 /// The leave notification is sent before the enter notification
347 /// for the new focus.
348 ///
349 /// # Arguments
350 ///
351 /// - `serial`: serial number of the leave event
352 /// - `surface`: surface left by the pointer
353 #[inline]
354 pub fn try_send_leave(
355 &self,
356 serial: u32,
357 surface: &Rc<WlSurface>,
358 ) -> Result<(), ObjectError> {
359 let (
360 arg0,
361 arg1,
362 ) = (
363 serial,
364 surface,
365 );
366 let arg1 = arg1.core();
367 let core = self.core();
368 let client_ref = core.client.borrow();
369 let Some(client) = &*client_ref else {
370 return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
371 };
372 let id = core.client_obj_id.get().unwrap_or(0);
373 if arg1.client_id.get() != Some(client.endpoint.id) {
374 return Err(ObjectError(ObjectErrorKind::ArgNoClientId("surface", client.endpoint.id)));
375 }
376 let arg1_id = arg1.client_obj_id.get().unwrap_or(0);
377 #[cfg(feature = "logging")]
378 if self.core.state.log {
379 #[cold]
380 fn log(state: &State, client_id: u64, id: u32, arg0: u32, arg1: u32) {
381 let (millis, micros) = time_since_epoch();
382 let prefix = &state.log_prefix;
383 let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_pointer#{}.leave(serial: {}, surface: wl_surface#{})\n", client_id, id, arg0, arg1);
384 state.log(args);
385 }
386 log(&self.core.state, client.endpoint.id, id, arg0, arg1_id);
387 }
388 let endpoint = &client.endpoint;
389 if !endpoint.flush_queued.replace(true) {
390 self.core.state.add_flushable_endpoint(endpoint, Some(client));
391 }
392 let mut outgoing_ref = endpoint.outgoing.borrow_mut();
393 let outgoing = &mut *outgoing_ref;
394 let mut fmt = outgoing.formatter();
395 fmt.words([
396 id,
397 1,
398 arg0,
399 arg1_id,
400 ]);
401 Ok(())
402 }
403
404 /// leave event
405 ///
406 /// Notification that this seat's pointer is no longer focused on
407 /// a certain surface.
408 ///
409 /// The leave notification is sent before the enter notification
410 /// for the new focus.
411 ///
412 /// # Arguments
413 ///
414 /// - `serial`: serial number of the leave event
415 /// - `surface`: surface left by the pointer
416 #[inline]
417 pub fn send_leave(
418 &self,
419 serial: u32,
420 surface: &Rc<WlSurface>,
421 ) {
422 let res = self.try_send_leave(
423 serial,
424 surface,
425 );
426 if let Err(e) = res {
427 log_send("wl_pointer.leave", &e);
428 }
429 }
430
431 /// Since when the motion message is available.
432 pub const MSG__MOTION__SINCE: u32 = 1;
433
434 /// pointer motion event
435 ///
436 /// Notification of pointer location change. The arguments
437 /// surface_x and surface_y are the location relative to the
438 /// focused surface.
439 ///
440 /// # Arguments
441 ///
442 /// - `time`: timestamp with millisecond granularity
443 /// - `surface_x`: surface-local x coordinate
444 /// - `surface_y`: surface-local y coordinate
445 #[inline]
446 pub fn try_send_motion(
447 &self,
448 time: u32,
449 surface_x: Fixed,
450 surface_y: Fixed,
451 ) -> Result<(), ObjectError> {
452 let (
453 arg0,
454 arg1,
455 arg2,
456 ) = (
457 time,
458 surface_x,
459 surface_y,
460 );
461 let core = self.core();
462 let client_ref = core.client.borrow();
463 let Some(client) = &*client_ref else {
464 return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
465 };
466 let id = core.client_obj_id.get().unwrap_or(0);
467 #[cfg(feature = "logging")]
468 if self.core.state.log {
469 #[cold]
470 fn log(state: &State, client_id: u64, id: u32, arg0: u32, arg1: Fixed, arg2: Fixed) {
471 let (millis, micros) = time_since_epoch();
472 let prefix = &state.log_prefix;
473 let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_pointer#{}.motion(time: {}, surface_x: {}, surface_y: {})\n", client_id, id, arg0, arg1, arg2);
474 state.log(args);
475 }
476 log(&self.core.state, client.endpoint.id, id, arg0, arg1, arg2);
477 }
478 let endpoint = &client.endpoint;
479 if !endpoint.flush_queued.replace(true) {
480 self.core.state.add_flushable_endpoint(endpoint, Some(client));
481 }
482 let mut outgoing_ref = endpoint.outgoing.borrow_mut();
483 let outgoing = &mut *outgoing_ref;
484 let mut fmt = outgoing.formatter();
485 fmt.words([
486 id,
487 2,
488 arg0,
489 arg1.to_wire() as u32,
490 arg2.to_wire() as u32,
491 ]);
492 Ok(())
493 }
494
495 /// pointer motion event
496 ///
497 /// Notification of pointer location change. The arguments
498 /// surface_x and surface_y are the location relative to the
499 /// focused surface.
500 ///
501 /// # Arguments
502 ///
503 /// - `time`: timestamp with millisecond granularity
504 /// - `surface_x`: surface-local x coordinate
505 /// - `surface_y`: surface-local y coordinate
506 #[inline]
507 pub fn send_motion(
508 &self,
509 time: u32,
510 surface_x: Fixed,
511 surface_y: Fixed,
512 ) {
513 let res = self.try_send_motion(
514 time,
515 surface_x,
516 surface_y,
517 );
518 if let Err(e) = res {
519 log_send("wl_pointer.motion", &e);
520 }
521 }
522
523 /// Since when the button message is available.
524 pub const MSG__BUTTON__SINCE: u32 = 1;
525
526 /// pointer button event
527 ///
528 /// Mouse button click and release notifications.
529 ///
530 /// The location of the click is given by the last motion or
531 /// enter event.
532 /// The time argument is a timestamp with millisecond
533 /// granularity, with an undefined base.
534 ///
535 /// The button is a button code as defined in the Linux kernel's
536 /// linux/input-event-codes.h header file, e.g. BTN_LEFT.
537 ///
538 /// Any 16-bit button code value is reserved for future additions to the
539 /// kernel's event code list. All other button codes above 0xFFFF are
540 /// currently undefined but may be used in future versions of this
541 /// protocol.
542 ///
543 /// # Arguments
544 ///
545 /// - `serial`: serial number of the button event
546 /// - `time`: timestamp with millisecond granularity
547 /// - `button`: button that produced the event
548 /// - `state`: physical state of the button
549 #[inline]
550 pub fn try_send_button(
551 &self,
552 serial: u32,
553 time: u32,
554 button: u32,
555 state: WlPointerButtonState,
556 ) -> Result<(), ObjectError> {
557 let (
558 arg0,
559 arg1,
560 arg2,
561 arg3,
562 ) = (
563 serial,
564 time,
565 button,
566 state,
567 );
568 let core = self.core();
569 let client_ref = core.client.borrow();
570 let Some(client) = &*client_ref else {
571 return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
572 };
573 let id = core.client_obj_id.get().unwrap_or(0);
574 #[cfg(feature = "logging")]
575 if self.core.state.log {
576 #[cold]
577 fn log(state: &State, client_id: u64, id: u32, arg0: u32, arg1: u32, arg2: u32, arg3: WlPointerButtonState) {
578 let (millis, micros) = time_since_epoch();
579 let prefix = &state.log_prefix;
580 let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_pointer#{}.button(serial: {}, time: {}, button: {}, state: {:?})\n", client_id, id, arg0, arg1, arg2, arg3);
581 state.log(args);
582 }
583 log(&self.core.state, client.endpoint.id, id, arg0, arg1, arg2, arg3);
584 }
585 let endpoint = &client.endpoint;
586 if !endpoint.flush_queued.replace(true) {
587 self.core.state.add_flushable_endpoint(endpoint, Some(client));
588 }
589 let mut outgoing_ref = endpoint.outgoing.borrow_mut();
590 let outgoing = &mut *outgoing_ref;
591 let mut fmt = outgoing.formatter();
592 fmt.words([
593 id,
594 3,
595 arg0,
596 arg1,
597 arg2,
598 arg3.0,
599 ]);
600 Ok(())
601 }
602
603 /// pointer button event
604 ///
605 /// Mouse button click and release notifications.
606 ///
607 /// The location of the click is given by the last motion or
608 /// enter event.
609 /// The time argument is a timestamp with millisecond
610 /// granularity, with an undefined base.
611 ///
612 /// The button is a button code as defined in the Linux kernel's
613 /// linux/input-event-codes.h header file, e.g. BTN_LEFT.
614 ///
615 /// Any 16-bit button code value is reserved for future additions to the
616 /// kernel's event code list. All other button codes above 0xFFFF are
617 /// currently undefined but may be used in future versions of this
618 /// protocol.
619 ///
620 /// # Arguments
621 ///
622 /// - `serial`: serial number of the button event
623 /// - `time`: timestamp with millisecond granularity
624 /// - `button`: button that produced the event
625 /// - `state`: physical state of the button
626 #[inline]
627 pub fn send_button(
628 &self,
629 serial: u32,
630 time: u32,
631 button: u32,
632 state: WlPointerButtonState,
633 ) {
634 let res = self.try_send_button(
635 serial,
636 time,
637 button,
638 state,
639 );
640 if let Err(e) = res {
641 log_send("wl_pointer.button", &e);
642 }
643 }
644
645 /// Since when the axis message is available.
646 pub const MSG__AXIS__SINCE: u32 = 1;
647
648 /// axis event
649 ///
650 /// Scroll and other axis notifications.
651 ///
652 /// For scroll events (vertical and horizontal scroll axes), the
653 /// value parameter is the length of a vector along the specified
654 /// axis in a coordinate space identical to those of motion events,
655 /// representing a relative movement along the specified axis.
656 ///
657 /// For devices that support movements non-parallel to axes multiple
658 /// axis events will be emitted.
659 ///
660 /// When applicable, for example for touch pads, the server can
661 /// choose to emit scroll events where the motion vector is
662 /// equivalent to a motion event vector.
663 ///
664 /// When applicable, a client can transform its content relative to the
665 /// scroll distance.
666 ///
667 /// # Arguments
668 ///
669 /// - `time`: timestamp with millisecond granularity
670 /// - `axis`: axis type
671 /// - `value`: length of vector in surface-local coordinate space
672 #[inline]
673 pub fn try_send_axis(
674 &self,
675 time: u32,
676 axis: WlPointerAxis,
677 value: Fixed,
678 ) -> Result<(), ObjectError> {
679 let (
680 arg0,
681 arg1,
682 arg2,
683 ) = (
684 time,
685 axis,
686 value,
687 );
688 let core = self.core();
689 let client_ref = core.client.borrow();
690 let Some(client) = &*client_ref else {
691 return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
692 };
693 let id = core.client_obj_id.get().unwrap_or(0);
694 #[cfg(feature = "logging")]
695 if self.core.state.log {
696 #[cold]
697 fn log(state: &State, client_id: u64, id: u32, arg0: u32, arg1: WlPointerAxis, arg2: Fixed) {
698 let (millis, micros) = time_since_epoch();
699 let prefix = &state.log_prefix;
700 let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_pointer#{}.axis(time: {}, axis: {:?}, value: {})\n", client_id, id, arg0, arg1, arg2);
701 state.log(args);
702 }
703 log(&self.core.state, client.endpoint.id, id, arg0, arg1, arg2);
704 }
705 let endpoint = &client.endpoint;
706 if !endpoint.flush_queued.replace(true) {
707 self.core.state.add_flushable_endpoint(endpoint, Some(client));
708 }
709 let mut outgoing_ref = endpoint.outgoing.borrow_mut();
710 let outgoing = &mut *outgoing_ref;
711 let mut fmt = outgoing.formatter();
712 fmt.words([
713 id,
714 4,
715 arg0,
716 arg1.0,
717 arg2.to_wire() as u32,
718 ]);
719 Ok(())
720 }
721
722 /// axis event
723 ///
724 /// Scroll and other axis notifications.
725 ///
726 /// For scroll events (vertical and horizontal scroll axes), the
727 /// value parameter is the length of a vector along the specified
728 /// axis in a coordinate space identical to those of motion events,
729 /// representing a relative movement along the specified axis.
730 ///
731 /// For devices that support movements non-parallel to axes multiple
732 /// axis events will be emitted.
733 ///
734 /// When applicable, for example for touch pads, the server can
735 /// choose to emit scroll events where the motion vector is
736 /// equivalent to a motion event vector.
737 ///
738 /// When applicable, a client can transform its content relative to the
739 /// scroll distance.
740 ///
741 /// # Arguments
742 ///
743 /// - `time`: timestamp with millisecond granularity
744 /// - `axis`: axis type
745 /// - `value`: length of vector in surface-local coordinate space
746 #[inline]
747 pub fn send_axis(
748 &self,
749 time: u32,
750 axis: WlPointerAxis,
751 value: Fixed,
752 ) {
753 let res = self.try_send_axis(
754 time,
755 axis,
756 value,
757 );
758 if let Err(e) = res {
759 log_send("wl_pointer.axis", &e);
760 }
761 }
762
763 /// Since when the release message is available.
764 pub const MSG__RELEASE__SINCE: u32 = 3;
765
766 /// release the pointer object
767 ///
768 /// Using this request a client can tell the server that it is not going to
769 /// use the pointer object anymore.
770 ///
771 /// This request destroys the pointer proxy object, so clients must not call
772 /// wl_pointer_destroy() after using this request.
773 #[inline]
774 pub fn try_send_release(
775 &self,
776 ) -> Result<(), ObjectError> {
777 let core = self.core();
778 let Some(id) = core.server_obj_id.get() else {
779 return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
780 };
781 #[cfg(feature = "logging")]
782 if self.core.state.log {
783 #[cold]
784 fn log(state: &State, id: u32) {
785 let (millis, micros) = time_since_epoch();
786 let prefix = &state.log_prefix;
787 let args = format_args!("[{millis:7}.{micros:03}] {prefix}server <= wl_pointer#{}.release()\n", id);
788 state.log(args);
789 }
790 log(&self.core.state, id);
791 }
792 let Some(endpoint) = &self.core.state.server else {
793 return Ok(());
794 };
795 if !endpoint.flush_queued.replace(true) {
796 self.core.state.add_flushable_endpoint(endpoint, None);
797 }
798 let mut outgoing_ref = endpoint.outgoing.borrow_mut();
799 let outgoing = &mut *outgoing_ref;
800 let mut fmt = outgoing.formatter();
801 fmt.words([
802 id,
803 1,
804 ]);
805 self.core.handle_server_destroy();
806 Ok(())
807 }
808
809 /// release the pointer object
810 ///
811 /// Using this request a client can tell the server that it is not going to
812 /// use the pointer object anymore.
813 ///
814 /// This request destroys the pointer proxy object, so clients must not call
815 /// wl_pointer_destroy() after using this request.
816 #[inline]
817 pub fn send_release(
818 &self,
819 ) {
820 let res = self.try_send_release(
821 );
822 if let Err(e) = res {
823 log_send("wl_pointer.release", &e);
824 }
825 }
826
827 /// Since when the frame message is available.
828 pub const MSG__FRAME__SINCE: u32 = 5;
829
830 /// end of a pointer event sequence
831 ///
832 /// Indicates the end of a set of events that logically belong together.
833 /// A client is expected to accumulate the data in all events within the
834 /// frame before proceeding.
835 ///
836 /// All wl_pointer events before a wl_pointer.frame event belong
837 /// logically together. For example, in a diagonal scroll motion the
838 /// compositor will send an optional wl_pointer.axis_source event, two
839 /// wl_pointer.axis events (horizontal and vertical) and finally a
840 /// wl_pointer.frame event. The client may use this information to
841 /// calculate a diagonal vector for scrolling.
842 ///
843 /// When multiple wl_pointer.axis events occur within the same frame,
844 /// the motion vector is the combined motion of all events.
845 /// When a wl_pointer.axis and a wl_pointer.axis_stop event occur within
846 /// the same frame, this indicates that axis movement in one axis has
847 /// stopped but continues in the other axis.
848 /// When multiple wl_pointer.axis_stop events occur within the same
849 /// frame, this indicates that these axes stopped in the same instance.
850 ///
851 /// A wl_pointer.frame event is sent for every logical event group,
852 /// even if the group only contains a single wl_pointer event.
853 /// Specifically, a client may get a sequence: motion, frame, button,
854 /// frame, axis, frame, axis_stop, frame.
855 ///
856 /// The wl_pointer.enter and wl_pointer.leave events are logical events
857 /// generated by the compositor and not the hardware. These events are
858 /// also grouped by a wl_pointer.frame. When a pointer moves from one
859 /// surface to another, a compositor should group the
860 /// wl_pointer.leave event within the same wl_pointer.frame.
861 /// However, a client must not rely on wl_pointer.leave and
862 /// wl_pointer.enter being in the same wl_pointer.frame.
863 /// Compositor-specific policies may require the wl_pointer.leave and
864 /// wl_pointer.enter event being split across multiple wl_pointer.frame
865 /// groups.
866 #[inline]
867 pub fn try_send_frame(
868 &self,
869 ) -> Result<(), ObjectError> {
870 let core = self.core();
871 let client_ref = core.client.borrow();
872 let Some(client) = &*client_ref else {
873 return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
874 };
875 let id = core.client_obj_id.get().unwrap_or(0);
876 #[cfg(feature = "logging")]
877 if self.core.state.log {
878 #[cold]
879 fn log(state: &State, client_id: u64, id: u32) {
880 let (millis, micros) = time_since_epoch();
881 let prefix = &state.log_prefix;
882 let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_pointer#{}.frame()\n", client_id, id);
883 state.log(args);
884 }
885 log(&self.core.state, client.endpoint.id, id);
886 }
887 let endpoint = &client.endpoint;
888 if !endpoint.flush_queued.replace(true) {
889 self.core.state.add_flushable_endpoint(endpoint, Some(client));
890 }
891 let mut outgoing_ref = endpoint.outgoing.borrow_mut();
892 let outgoing = &mut *outgoing_ref;
893 let mut fmt = outgoing.formatter();
894 fmt.words([
895 id,
896 5,
897 ]);
898 Ok(())
899 }
900
901 /// end of a pointer event sequence
902 ///
903 /// Indicates the end of a set of events that logically belong together.
904 /// A client is expected to accumulate the data in all events within the
905 /// frame before proceeding.
906 ///
907 /// All wl_pointer events before a wl_pointer.frame event belong
908 /// logically together. For example, in a diagonal scroll motion the
909 /// compositor will send an optional wl_pointer.axis_source event, two
910 /// wl_pointer.axis events (horizontal and vertical) and finally a
911 /// wl_pointer.frame event. The client may use this information to
912 /// calculate a diagonal vector for scrolling.
913 ///
914 /// When multiple wl_pointer.axis events occur within the same frame,
915 /// the motion vector is the combined motion of all events.
916 /// When a wl_pointer.axis and a wl_pointer.axis_stop event occur within
917 /// the same frame, this indicates that axis movement in one axis has
918 /// stopped but continues in the other axis.
919 /// When multiple wl_pointer.axis_stop events occur within the same
920 /// frame, this indicates that these axes stopped in the same instance.
921 ///
922 /// A wl_pointer.frame event is sent for every logical event group,
923 /// even if the group only contains a single wl_pointer event.
924 /// Specifically, a client may get a sequence: motion, frame, button,
925 /// frame, axis, frame, axis_stop, frame.
926 ///
927 /// The wl_pointer.enter and wl_pointer.leave events are logical events
928 /// generated by the compositor and not the hardware. These events are
929 /// also grouped by a wl_pointer.frame. When a pointer moves from one
930 /// surface to another, a compositor should group the
931 /// wl_pointer.leave event within the same wl_pointer.frame.
932 /// However, a client must not rely on wl_pointer.leave and
933 /// wl_pointer.enter being in the same wl_pointer.frame.
934 /// Compositor-specific policies may require the wl_pointer.leave and
935 /// wl_pointer.enter event being split across multiple wl_pointer.frame
936 /// groups.
937 #[inline]
938 pub fn send_frame(
939 &self,
940 ) {
941 let res = self.try_send_frame(
942 );
943 if let Err(e) = res {
944 log_send("wl_pointer.frame", &e);
945 }
946 }
947
948 /// Since when the axis_source message is available.
949 pub const MSG__AXIS_SOURCE__SINCE: u32 = 5;
950
951 /// axis source event
952 ///
953 /// Source information for scroll and other axes.
954 ///
955 /// This event does not occur on its own. It is sent before a
956 /// wl_pointer.frame event and carries the source information for
957 /// all events within that frame.
958 ///
959 /// The source specifies how this event was generated. If the source is
960 /// wl_pointer.axis_source.finger, a wl_pointer.axis_stop event will be
961 /// sent when the user lifts the finger off the device.
962 ///
963 /// If the source is wl_pointer.axis_source.wheel,
964 /// wl_pointer.axis_source.wheel_tilt or
965 /// wl_pointer.axis_source.continuous, a wl_pointer.axis_stop event may
966 /// or may not be sent. Whether a compositor sends an axis_stop event
967 /// for these sources is hardware-specific and implementation-dependent;
968 /// clients must not rely on receiving an axis_stop event for these
969 /// scroll sources and should treat scroll sequences from these scroll
970 /// sources as unterminated by default.
971 ///
972 /// This event is optional. If the source is unknown for a particular
973 /// axis event sequence, no event is sent.
974 /// Only one wl_pointer.axis_source event is permitted per frame.
975 ///
976 /// The order of wl_pointer.axis_discrete and wl_pointer.axis_source is
977 /// not guaranteed.
978 ///
979 /// # Arguments
980 ///
981 /// - `axis_source`: source of the axis event
982 #[inline]
983 pub fn try_send_axis_source(
984 &self,
985 axis_source: WlPointerAxisSource,
986 ) -> Result<(), ObjectError> {
987 let (
988 arg0,
989 ) = (
990 axis_source,
991 );
992 let core = self.core();
993 let client_ref = core.client.borrow();
994 let Some(client) = &*client_ref else {
995 return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
996 };
997 let id = core.client_obj_id.get().unwrap_or(0);
998 #[cfg(feature = "logging")]
999 if self.core.state.log {
1000 #[cold]
1001 fn log(state: &State, client_id: u64, id: u32, arg0: WlPointerAxisSource) {
1002 let (millis, micros) = time_since_epoch();
1003 let prefix = &state.log_prefix;
1004 let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_pointer#{}.axis_source(axis_source: {:?})\n", client_id, id, arg0);
1005 state.log(args);
1006 }
1007 log(&self.core.state, client.endpoint.id, id, arg0);
1008 }
1009 let endpoint = &client.endpoint;
1010 if !endpoint.flush_queued.replace(true) {
1011 self.core.state.add_flushable_endpoint(endpoint, Some(client));
1012 }
1013 let mut outgoing_ref = endpoint.outgoing.borrow_mut();
1014 let outgoing = &mut *outgoing_ref;
1015 let mut fmt = outgoing.formatter();
1016 fmt.words([
1017 id,
1018 6,
1019 arg0.0,
1020 ]);
1021 Ok(())
1022 }
1023
1024 /// axis source event
1025 ///
1026 /// Source information for scroll and other axes.
1027 ///
1028 /// This event does not occur on its own. It is sent before a
1029 /// wl_pointer.frame event and carries the source information for
1030 /// all events within that frame.
1031 ///
1032 /// The source specifies how this event was generated. If the source is
1033 /// wl_pointer.axis_source.finger, a wl_pointer.axis_stop event will be
1034 /// sent when the user lifts the finger off the device.
1035 ///
1036 /// If the source is wl_pointer.axis_source.wheel,
1037 /// wl_pointer.axis_source.wheel_tilt or
1038 /// wl_pointer.axis_source.continuous, a wl_pointer.axis_stop event may
1039 /// or may not be sent. Whether a compositor sends an axis_stop event
1040 /// for these sources is hardware-specific and implementation-dependent;
1041 /// clients must not rely on receiving an axis_stop event for these
1042 /// scroll sources and should treat scroll sequences from these scroll
1043 /// sources as unterminated by default.
1044 ///
1045 /// This event is optional. If the source is unknown for a particular
1046 /// axis event sequence, no event is sent.
1047 /// Only one wl_pointer.axis_source event is permitted per frame.
1048 ///
1049 /// The order of wl_pointer.axis_discrete and wl_pointer.axis_source is
1050 /// not guaranteed.
1051 ///
1052 /// # Arguments
1053 ///
1054 /// - `axis_source`: source of the axis event
1055 #[inline]
1056 pub fn send_axis_source(
1057 &self,
1058 axis_source: WlPointerAxisSource,
1059 ) {
1060 let res = self.try_send_axis_source(
1061 axis_source,
1062 );
1063 if let Err(e) = res {
1064 log_send("wl_pointer.axis_source", &e);
1065 }
1066 }
1067
1068 /// Since when the axis_stop message is available.
1069 pub const MSG__AXIS_STOP__SINCE: u32 = 5;
1070
1071 /// axis stop event
1072 ///
1073 /// Stop notification for scroll and other axes.
1074 ///
1075 /// For some wl_pointer.axis_source types, a wl_pointer.axis_stop event
1076 /// is sent to notify a client that the axis sequence has terminated.
1077 /// This enables the client to implement kinetic scrolling.
1078 /// See the wl_pointer.axis_source documentation for information on when
1079 /// this event may be generated.
1080 ///
1081 /// Any wl_pointer.axis events with the same axis_source after this
1082 /// event should be considered as the start of a new axis motion.
1083 ///
1084 /// The timestamp is to be interpreted identical to the timestamp in the
1085 /// wl_pointer.axis event. The timestamp value may be the same as a
1086 /// preceding wl_pointer.axis event.
1087 ///
1088 /// # Arguments
1089 ///
1090 /// - `time`: timestamp with millisecond granularity
1091 /// - `axis`: the axis stopped with this event
1092 #[inline]
1093 pub fn try_send_axis_stop(
1094 &self,
1095 time: u32,
1096 axis: WlPointerAxis,
1097 ) -> Result<(), ObjectError> {
1098 let (
1099 arg0,
1100 arg1,
1101 ) = (
1102 time,
1103 axis,
1104 );
1105 let core = self.core();
1106 let client_ref = core.client.borrow();
1107 let Some(client) = &*client_ref else {
1108 return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
1109 };
1110 let id = core.client_obj_id.get().unwrap_or(0);
1111 #[cfg(feature = "logging")]
1112 if self.core.state.log {
1113 #[cold]
1114 fn log(state: &State, client_id: u64, id: u32, arg0: u32, arg1: WlPointerAxis) {
1115 let (millis, micros) = time_since_epoch();
1116 let prefix = &state.log_prefix;
1117 let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_pointer#{}.axis_stop(time: {}, axis: {:?})\n", client_id, id, arg0, arg1);
1118 state.log(args);
1119 }
1120 log(&self.core.state, client.endpoint.id, id, arg0, arg1);
1121 }
1122 let endpoint = &client.endpoint;
1123 if !endpoint.flush_queued.replace(true) {
1124 self.core.state.add_flushable_endpoint(endpoint, Some(client));
1125 }
1126 let mut outgoing_ref = endpoint.outgoing.borrow_mut();
1127 let outgoing = &mut *outgoing_ref;
1128 let mut fmt = outgoing.formatter();
1129 fmt.words([
1130 id,
1131 7,
1132 arg0,
1133 arg1.0,
1134 ]);
1135 Ok(())
1136 }
1137
1138 /// axis stop event
1139 ///
1140 /// Stop notification for scroll and other axes.
1141 ///
1142 /// For some wl_pointer.axis_source types, a wl_pointer.axis_stop event
1143 /// is sent to notify a client that the axis sequence has terminated.
1144 /// This enables the client to implement kinetic scrolling.
1145 /// See the wl_pointer.axis_source documentation for information on when
1146 /// this event may be generated.
1147 ///
1148 /// Any wl_pointer.axis events with the same axis_source after this
1149 /// event should be considered as the start of a new axis motion.
1150 ///
1151 /// The timestamp is to be interpreted identical to the timestamp in the
1152 /// wl_pointer.axis event. The timestamp value may be the same as a
1153 /// preceding wl_pointer.axis event.
1154 ///
1155 /// # Arguments
1156 ///
1157 /// - `time`: timestamp with millisecond granularity
1158 /// - `axis`: the axis stopped with this event
1159 #[inline]
1160 pub fn send_axis_stop(
1161 &self,
1162 time: u32,
1163 axis: WlPointerAxis,
1164 ) {
1165 let res = self.try_send_axis_stop(
1166 time,
1167 axis,
1168 );
1169 if let Err(e) = res {
1170 log_send("wl_pointer.axis_stop", &e);
1171 }
1172 }
1173
1174 /// Since when the axis_discrete message is available.
1175 pub const MSG__AXIS_DISCRETE__SINCE: u32 = 5;
1176
1177 /// Since when the axis_discrete message is deprecated.
1178 pub const MSG__AXIS_DISCRETE__DEPRECATED_SINCE: u32 = 8;
1179
1180 /// axis click event
1181 ///
1182 /// Discrete step information for scroll and other axes.
1183 ///
1184 /// This event carries the axis value of the wl_pointer.axis event in
1185 /// discrete steps (e.g. mouse wheel clicks).
1186 ///
1187 /// This event is deprecated with wl_pointer version 8 - this event is not
1188 /// sent to clients supporting version 8 or later.
1189 ///
1190 /// This event does not occur on its own, it is coupled with a
1191 /// wl_pointer.axis event that represents this axis value on a
1192 /// continuous scale. The protocol guarantees that each axis_discrete
1193 /// event is always followed by exactly one axis event with the same
1194 /// axis number within the same wl_pointer.frame. Note that the protocol
1195 /// allows for other events to occur between the axis_discrete and
1196 /// its coupled axis event, including other axis_discrete or axis
1197 /// events. A wl_pointer.frame must not contain more than one axis_discrete
1198 /// event per axis type.
1199 ///
1200 /// This event is optional; continuous scrolling devices
1201 /// like two-finger scrolling on touchpads do not have discrete
1202 /// steps and do not generate this event.
1203 ///
1204 /// The discrete value carries the directional information. e.g. a value
1205 /// of -2 is two steps towards the negative direction of this axis.
1206 ///
1207 /// The axis number is identical to the axis number in the associated
1208 /// axis event.
1209 ///
1210 /// The order of wl_pointer.axis_discrete and wl_pointer.axis_source is
1211 /// not guaranteed.
1212 ///
1213 /// # Arguments
1214 ///
1215 /// - `axis`: axis type
1216 /// - `discrete`: number of steps
1217 #[inline]
1218 pub fn try_send_axis_discrete(
1219 &self,
1220 axis: WlPointerAxis,
1221 discrete: i32,
1222 ) -> Result<(), ObjectError> {
1223 let (
1224 arg0,
1225 arg1,
1226 ) = (
1227 axis,
1228 discrete,
1229 );
1230 let core = self.core();
1231 let client_ref = core.client.borrow();
1232 let Some(client) = &*client_ref else {
1233 return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
1234 };
1235 let id = core.client_obj_id.get().unwrap_or(0);
1236 #[cfg(feature = "logging")]
1237 if self.core.state.log {
1238 #[cold]
1239 fn log(state: &State, client_id: u64, id: u32, arg0: WlPointerAxis, arg1: i32) {
1240 let (millis, micros) = time_since_epoch();
1241 let prefix = &state.log_prefix;
1242 let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_pointer#{}.axis_discrete(axis: {:?}, discrete: {})\n", client_id, id, arg0, arg1);
1243 state.log(args);
1244 }
1245 log(&self.core.state, client.endpoint.id, id, arg0, arg1);
1246 }
1247 let endpoint = &client.endpoint;
1248 if !endpoint.flush_queued.replace(true) {
1249 self.core.state.add_flushable_endpoint(endpoint, Some(client));
1250 }
1251 let mut outgoing_ref = endpoint.outgoing.borrow_mut();
1252 let outgoing = &mut *outgoing_ref;
1253 let mut fmt = outgoing.formatter();
1254 fmt.words([
1255 id,
1256 8,
1257 arg0.0,
1258 arg1 as u32,
1259 ]);
1260 Ok(())
1261 }
1262
1263 /// axis click event
1264 ///
1265 /// Discrete step information for scroll and other axes.
1266 ///
1267 /// This event carries the axis value of the wl_pointer.axis event in
1268 /// discrete steps (e.g. mouse wheel clicks).
1269 ///
1270 /// This event is deprecated with wl_pointer version 8 - this event is not
1271 /// sent to clients supporting version 8 or later.
1272 ///
1273 /// This event does not occur on its own, it is coupled with a
1274 /// wl_pointer.axis event that represents this axis value on a
1275 /// continuous scale. The protocol guarantees that each axis_discrete
1276 /// event is always followed by exactly one axis event with the same
1277 /// axis number within the same wl_pointer.frame. Note that the protocol
1278 /// allows for other events to occur between the axis_discrete and
1279 /// its coupled axis event, including other axis_discrete or axis
1280 /// events. A wl_pointer.frame must not contain more than one axis_discrete
1281 /// event per axis type.
1282 ///
1283 /// This event is optional; continuous scrolling devices
1284 /// like two-finger scrolling on touchpads do not have discrete
1285 /// steps and do not generate this event.
1286 ///
1287 /// The discrete value carries the directional information. e.g. a value
1288 /// of -2 is two steps towards the negative direction of this axis.
1289 ///
1290 /// The axis number is identical to the axis number in the associated
1291 /// axis event.
1292 ///
1293 /// The order of wl_pointer.axis_discrete and wl_pointer.axis_source is
1294 /// not guaranteed.
1295 ///
1296 /// # Arguments
1297 ///
1298 /// - `axis`: axis type
1299 /// - `discrete`: number of steps
1300 #[inline]
1301 pub fn send_axis_discrete(
1302 &self,
1303 axis: WlPointerAxis,
1304 discrete: i32,
1305 ) {
1306 let res = self.try_send_axis_discrete(
1307 axis,
1308 discrete,
1309 );
1310 if let Err(e) = res {
1311 log_send("wl_pointer.axis_discrete", &e);
1312 }
1313 }
1314
1315 /// Since when the axis_value120 message is available.
1316 pub const MSG__AXIS_VALUE120__SINCE: u32 = 8;
1317
1318 /// axis high-resolution scroll event
1319 ///
1320 /// Discrete high-resolution scroll information.
1321 ///
1322 /// This event carries high-resolution wheel scroll information,
1323 /// with each multiple of 120 representing one logical scroll step
1324 /// (a wheel detent). For example, an axis_value120 of 30 is one quarter of
1325 /// a logical scroll step in the positive direction, a value120 of
1326 /// -240 are two logical scroll steps in the negative direction within the
1327 /// same hardware event.
1328 /// Clients that rely on discrete scrolling should accumulate the
1329 /// value120 to multiples of 120 before processing the event.
1330 ///
1331 /// The value120 must not be zero.
1332 ///
1333 /// This event replaces the wl_pointer.axis_discrete event in clients
1334 /// supporting wl_pointer version 8 or later.
1335 ///
1336 /// Where a wl_pointer.axis_source event occurs in the same
1337 /// wl_pointer.frame, the axis source applies to this event.
1338 ///
1339 /// The order of wl_pointer.axis_value120 and wl_pointer.axis_source is
1340 /// not guaranteed.
1341 ///
1342 /// # Arguments
1343 ///
1344 /// - `axis`: axis type
1345 /// - `value120`: scroll distance as fraction of 120
1346 #[inline]
1347 pub fn try_send_axis_value120(
1348 &self,
1349 axis: WlPointerAxis,
1350 value120: i32,
1351 ) -> Result<(), ObjectError> {
1352 let (
1353 arg0,
1354 arg1,
1355 ) = (
1356 axis,
1357 value120,
1358 );
1359 let core = self.core();
1360 let client_ref = core.client.borrow();
1361 let Some(client) = &*client_ref else {
1362 return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
1363 };
1364 let id = core.client_obj_id.get().unwrap_or(0);
1365 #[cfg(feature = "logging")]
1366 if self.core.state.log {
1367 #[cold]
1368 fn log(state: &State, client_id: u64, id: u32, arg0: WlPointerAxis, arg1: i32) {
1369 let (millis, micros) = time_since_epoch();
1370 let prefix = &state.log_prefix;
1371 let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_pointer#{}.axis_value120(axis: {:?}, value120: {})\n", client_id, id, arg0, arg1);
1372 state.log(args);
1373 }
1374 log(&self.core.state, client.endpoint.id, id, arg0, arg1);
1375 }
1376 let endpoint = &client.endpoint;
1377 if !endpoint.flush_queued.replace(true) {
1378 self.core.state.add_flushable_endpoint(endpoint, Some(client));
1379 }
1380 let mut outgoing_ref = endpoint.outgoing.borrow_mut();
1381 let outgoing = &mut *outgoing_ref;
1382 let mut fmt = outgoing.formatter();
1383 fmt.words([
1384 id,
1385 9,
1386 arg0.0,
1387 arg1 as u32,
1388 ]);
1389 Ok(())
1390 }
1391
1392 /// axis high-resolution scroll event
1393 ///
1394 /// Discrete high-resolution scroll information.
1395 ///
1396 /// This event carries high-resolution wheel scroll information,
1397 /// with each multiple of 120 representing one logical scroll step
1398 /// (a wheel detent). For example, an axis_value120 of 30 is one quarter of
1399 /// a logical scroll step in the positive direction, a value120 of
1400 /// -240 are two logical scroll steps in the negative direction within the
1401 /// same hardware event.
1402 /// Clients that rely on discrete scrolling should accumulate the
1403 /// value120 to multiples of 120 before processing the event.
1404 ///
1405 /// The value120 must not be zero.
1406 ///
1407 /// This event replaces the wl_pointer.axis_discrete event in clients
1408 /// supporting wl_pointer version 8 or later.
1409 ///
1410 /// Where a wl_pointer.axis_source event occurs in the same
1411 /// wl_pointer.frame, the axis source applies to this event.
1412 ///
1413 /// The order of wl_pointer.axis_value120 and wl_pointer.axis_source is
1414 /// not guaranteed.
1415 ///
1416 /// # Arguments
1417 ///
1418 /// - `axis`: axis type
1419 /// - `value120`: scroll distance as fraction of 120
1420 #[inline]
1421 pub fn send_axis_value120(
1422 &self,
1423 axis: WlPointerAxis,
1424 value120: i32,
1425 ) {
1426 let res = self.try_send_axis_value120(
1427 axis,
1428 value120,
1429 );
1430 if let Err(e) = res {
1431 log_send("wl_pointer.axis_value120", &e);
1432 }
1433 }
1434
1435 /// Since when the axis_relative_direction message is available.
1436 pub const MSG__AXIS_RELATIVE_DIRECTION__SINCE: u32 = 9;
1437
1438 /// axis relative physical direction event
1439 ///
1440 /// Relative directional information of the entity causing the axis
1441 /// motion.
1442 ///
1443 /// For a wl_pointer.axis event, the wl_pointer.axis_relative_direction
1444 /// event specifies the movement direction of the entity causing the
1445 /// wl_pointer.axis event. For example:
1446 /// - if a user's fingers on a touchpad move down and this
1447 /// causes a wl_pointer.axis vertical_scroll down event, the physical
1448 /// direction is 'identical'
1449 /// - if a user's fingers on a touchpad move down and this causes a
1450 /// wl_pointer.axis vertical_scroll up scroll up event ('natural
1451 /// scrolling'), the physical direction is 'inverted'.
1452 ///
1453 /// A client may use this information to adjust scroll motion of
1454 /// components. Specifically, enabling natural scrolling causes the
1455 /// content to change direction compared to traditional scrolling.
1456 /// Some widgets like volume control sliders should usually match the
1457 /// physical direction regardless of whether natural scrolling is
1458 /// active. This event enables clients to match the scroll direction of
1459 /// a widget to the physical direction.
1460 ///
1461 /// This event does not occur on its own, it is coupled with a
1462 /// wl_pointer.axis event that represents this axis value.
1463 /// The protocol guarantees that each axis_relative_direction event is
1464 /// always followed by exactly one axis event with the same
1465 /// axis number within the same wl_pointer.frame. Note that the protocol
1466 /// allows for other events to occur between the axis_relative_direction
1467 /// and its coupled axis event.
1468 ///
1469 /// The axis number is identical to the axis number in the associated
1470 /// axis event.
1471 ///
1472 /// The order of wl_pointer.axis_relative_direction,
1473 /// wl_pointer.axis_discrete and wl_pointer.axis_source is not
1474 /// guaranteed.
1475 ///
1476 /// # Arguments
1477 ///
1478 /// - `axis`: axis type
1479 /// - `direction`: physical direction relative to axis motion
1480 #[inline]
1481 pub fn try_send_axis_relative_direction(
1482 &self,
1483 axis: WlPointerAxis,
1484 direction: WlPointerAxisRelativeDirection,
1485 ) -> Result<(), ObjectError> {
1486 let (
1487 arg0,
1488 arg1,
1489 ) = (
1490 axis,
1491 direction,
1492 );
1493 let core = self.core();
1494 let client_ref = core.client.borrow();
1495 let Some(client) = &*client_ref else {
1496 return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
1497 };
1498 let id = core.client_obj_id.get().unwrap_or(0);
1499 #[cfg(feature = "logging")]
1500 if self.core.state.log {
1501 #[cold]
1502 fn log(state: &State, client_id: u64, id: u32, arg0: WlPointerAxis, arg1: WlPointerAxisRelativeDirection) {
1503 let (millis, micros) = time_since_epoch();
1504 let prefix = &state.log_prefix;
1505 let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_pointer#{}.axis_relative_direction(axis: {:?}, direction: {:?})\n", client_id, id, arg0, arg1);
1506 state.log(args);
1507 }
1508 log(&self.core.state, client.endpoint.id, id, arg0, arg1);
1509 }
1510 let endpoint = &client.endpoint;
1511 if !endpoint.flush_queued.replace(true) {
1512 self.core.state.add_flushable_endpoint(endpoint, Some(client));
1513 }
1514 let mut outgoing_ref = endpoint.outgoing.borrow_mut();
1515 let outgoing = &mut *outgoing_ref;
1516 let mut fmt = outgoing.formatter();
1517 fmt.words([
1518 id,
1519 10,
1520 arg0.0,
1521 arg1.0,
1522 ]);
1523 Ok(())
1524 }
1525
1526 /// axis relative physical direction event
1527 ///
1528 /// Relative directional information of the entity causing the axis
1529 /// motion.
1530 ///
1531 /// For a wl_pointer.axis event, the wl_pointer.axis_relative_direction
1532 /// event specifies the movement direction of the entity causing the
1533 /// wl_pointer.axis event. For example:
1534 /// - if a user's fingers on a touchpad move down and this
1535 /// causes a wl_pointer.axis vertical_scroll down event, the physical
1536 /// direction is 'identical'
1537 /// - if a user's fingers on a touchpad move down and this causes a
1538 /// wl_pointer.axis vertical_scroll up scroll up event ('natural
1539 /// scrolling'), the physical direction is 'inverted'.
1540 ///
1541 /// A client may use this information to adjust scroll motion of
1542 /// components. Specifically, enabling natural scrolling causes the
1543 /// content to change direction compared to traditional scrolling.
1544 /// Some widgets like volume control sliders should usually match the
1545 /// physical direction regardless of whether natural scrolling is
1546 /// active. This event enables clients to match the scroll direction of
1547 /// a widget to the physical direction.
1548 ///
1549 /// This event does not occur on its own, it is coupled with a
1550 /// wl_pointer.axis event that represents this axis value.
1551 /// The protocol guarantees that each axis_relative_direction event is
1552 /// always followed by exactly one axis event with the same
1553 /// axis number within the same wl_pointer.frame. Note that the protocol
1554 /// allows for other events to occur between the axis_relative_direction
1555 /// and its coupled axis event.
1556 ///
1557 /// The axis number is identical to the axis number in the associated
1558 /// axis event.
1559 ///
1560 /// The order of wl_pointer.axis_relative_direction,
1561 /// wl_pointer.axis_discrete and wl_pointer.axis_source is not
1562 /// guaranteed.
1563 ///
1564 /// # Arguments
1565 ///
1566 /// - `axis`: axis type
1567 /// - `direction`: physical direction relative to axis motion
1568 #[inline]
1569 pub fn send_axis_relative_direction(
1570 &self,
1571 axis: WlPointerAxis,
1572 direction: WlPointerAxisRelativeDirection,
1573 ) {
1574 let res = self.try_send_axis_relative_direction(
1575 axis,
1576 direction,
1577 );
1578 if let Err(e) = res {
1579 log_send("wl_pointer.axis_relative_direction", &e);
1580 }
1581 }
1582}
1583
1584/// A message handler for [`WlPointer`] proxies.
1585pub trait WlPointerHandler: Any {
1586 /// Event handler for wl_display.delete_id messages deleting the ID of this object.
1587 ///
1588 /// The default handler forwards the event to the client, if any.
1589 #[inline]
1590 fn delete_id(&mut self, slf: &Rc<WlPointer>) {
1591 slf.core.delete_id();
1592 }
1593
1594 /// set the pointer surface
1595 ///
1596 /// Set the pointer surface, i.e., the surface that contains the
1597 /// pointer image (cursor). This request gives the surface the role
1598 /// of a cursor. If the surface already has another role, it raises
1599 /// a protocol error.
1600 ///
1601 /// The cursor actually changes only if the pointer
1602 /// focus for this device is one of the requesting client's surfaces
1603 /// or the surface parameter is the current pointer surface. If
1604 /// there was a previous surface set with this request it is
1605 /// replaced. If surface is NULL, the pointer image is hidden.
1606 ///
1607 /// The parameters hotspot_x and hotspot_y define the position of
1608 /// the pointer surface relative to the pointer location. Its
1609 /// top-left corner is always at (x, y) - (hotspot_x, hotspot_y),
1610 /// where (x, y) are the coordinates of the pointer location, in
1611 /// surface-local coordinates.
1612 ///
1613 /// On wl_surface.offset requests to the pointer surface, hotspot_x
1614 /// and hotspot_y are decremented by the x and y parameters
1615 /// passed to the request. The offset must be applied by
1616 /// wl_surface.commit as usual.
1617 ///
1618 /// The hotspot can also be updated by passing the currently set
1619 /// pointer surface to this request with new values for hotspot_x
1620 /// and hotspot_y.
1621 ///
1622 /// The input region is ignored for wl_surfaces with the role of
1623 /// a cursor. When the use as a cursor ends, the wl_surface is
1624 /// unmapped.
1625 ///
1626 /// The serial parameter must match the latest wl_pointer.enter
1627 /// serial number sent to the client. Otherwise the request will be
1628 /// ignored.
1629 ///
1630 /// # Arguments
1631 ///
1632 /// - `serial`: serial number of the enter event
1633 /// - `surface`: pointer surface
1634 /// - `hotspot_x`: surface-local x coordinate
1635 /// - `hotspot_y`: surface-local y coordinate
1636 ///
1637 /// All borrowed proxies passed to this function are guaranteed to be
1638 /// immutable and non-null.
1639 #[inline]
1640 fn handle_set_cursor(
1641 &mut self,
1642 slf: &Rc<WlPointer>,
1643 serial: u32,
1644 surface: Option<&Rc<WlSurface>>,
1645 hotspot_x: i32,
1646 hotspot_y: i32,
1647 ) {
1648 if !slf.core.forward_to_server.get() {
1649 return;
1650 }
1651 let res = slf.try_send_set_cursor(
1652 serial,
1653 surface,
1654 hotspot_x,
1655 hotspot_y,
1656 );
1657 if let Err(e) = res {
1658 log_forward("wl_pointer.set_cursor", &e);
1659 }
1660 }
1661
1662 /// enter event
1663 ///
1664 /// Notification that this seat's pointer is focused on a certain
1665 /// surface.
1666 ///
1667 /// When a seat's focus enters a surface, the pointer image
1668 /// is undefined and a client should respond to this event by setting
1669 /// an appropriate pointer image with the set_cursor request.
1670 ///
1671 /// # Arguments
1672 ///
1673 /// - `serial`: serial number of the enter event
1674 /// - `surface`: surface entered by the pointer
1675 /// - `surface_x`: surface-local x coordinate
1676 /// - `surface_y`: surface-local y coordinate
1677 ///
1678 /// All borrowed proxies passed to this function are guaranteed to be
1679 /// immutable and non-null.
1680 #[inline]
1681 fn handle_enter(
1682 &mut self,
1683 slf: &Rc<WlPointer>,
1684 serial: u32,
1685 surface: &Rc<WlSurface>,
1686 surface_x: Fixed,
1687 surface_y: Fixed,
1688 ) {
1689 if !slf.core.forward_to_client.get() {
1690 return;
1691 }
1692 if let Some(client_id) = slf.core.client_id.get() {
1693 if let Some(client_id_2) = surface.core().client_id.get() {
1694 if client_id != client_id_2 {
1695 return;
1696 }
1697 }
1698 }
1699 let res = slf.try_send_enter(
1700 serial,
1701 surface,
1702 surface_x,
1703 surface_y,
1704 );
1705 if let Err(e) = res {
1706 log_forward("wl_pointer.enter", &e);
1707 }
1708 }
1709
1710 /// leave event
1711 ///
1712 /// Notification that this seat's pointer is no longer focused on
1713 /// a certain surface.
1714 ///
1715 /// The leave notification is sent before the enter notification
1716 /// for the new focus.
1717 ///
1718 /// # Arguments
1719 ///
1720 /// - `serial`: serial number of the leave event
1721 /// - `surface`: surface left by the pointer
1722 ///
1723 /// All borrowed proxies passed to this function are guaranteed to be
1724 /// immutable and non-null.
1725 #[inline]
1726 fn handle_leave(
1727 &mut self,
1728 slf: &Rc<WlPointer>,
1729 serial: u32,
1730 surface: &Rc<WlSurface>,
1731 ) {
1732 if !slf.core.forward_to_client.get() {
1733 return;
1734 }
1735 if let Some(client_id) = slf.core.client_id.get() {
1736 if let Some(client_id_2) = surface.core().client_id.get() {
1737 if client_id != client_id_2 {
1738 return;
1739 }
1740 }
1741 }
1742 let res = slf.try_send_leave(
1743 serial,
1744 surface,
1745 );
1746 if let Err(e) = res {
1747 log_forward("wl_pointer.leave", &e);
1748 }
1749 }
1750
1751 /// pointer motion event
1752 ///
1753 /// Notification of pointer location change. The arguments
1754 /// surface_x and surface_y are the location relative to the
1755 /// focused surface.
1756 ///
1757 /// # Arguments
1758 ///
1759 /// - `time`: timestamp with millisecond granularity
1760 /// - `surface_x`: surface-local x coordinate
1761 /// - `surface_y`: surface-local y coordinate
1762 #[inline]
1763 fn handle_motion(
1764 &mut self,
1765 slf: &Rc<WlPointer>,
1766 time: u32,
1767 surface_x: Fixed,
1768 surface_y: Fixed,
1769 ) {
1770 if !slf.core.forward_to_client.get() {
1771 return;
1772 }
1773 let res = slf.try_send_motion(
1774 time,
1775 surface_x,
1776 surface_y,
1777 );
1778 if let Err(e) = res {
1779 log_forward("wl_pointer.motion", &e);
1780 }
1781 }
1782
1783 /// pointer button event
1784 ///
1785 /// Mouse button click and release notifications.
1786 ///
1787 /// The location of the click is given by the last motion or
1788 /// enter event.
1789 /// The time argument is a timestamp with millisecond
1790 /// granularity, with an undefined base.
1791 ///
1792 /// The button is a button code as defined in the Linux kernel's
1793 /// linux/input-event-codes.h header file, e.g. BTN_LEFT.
1794 ///
1795 /// Any 16-bit button code value is reserved for future additions to the
1796 /// kernel's event code list. All other button codes above 0xFFFF are
1797 /// currently undefined but may be used in future versions of this
1798 /// protocol.
1799 ///
1800 /// # Arguments
1801 ///
1802 /// - `serial`: serial number of the button event
1803 /// - `time`: timestamp with millisecond granularity
1804 /// - `button`: button that produced the event
1805 /// - `state`: physical state of the button
1806 #[inline]
1807 fn handle_button(
1808 &mut self,
1809 slf: &Rc<WlPointer>,
1810 serial: u32,
1811 time: u32,
1812 button: u32,
1813 state: WlPointerButtonState,
1814 ) {
1815 if !slf.core.forward_to_client.get() {
1816 return;
1817 }
1818 let res = slf.try_send_button(
1819 serial,
1820 time,
1821 button,
1822 state,
1823 );
1824 if let Err(e) = res {
1825 log_forward("wl_pointer.button", &e);
1826 }
1827 }
1828
1829 /// axis event
1830 ///
1831 /// Scroll and other axis notifications.
1832 ///
1833 /// For scroll events (vertical and horizontal scroll axes), the
1834 /// value parameter is the length of a vector along the specified
1835 /// axis in a coordinate space identical to those of motion events,
1836 /// representing a relative movement along the specified axis.
1837 ///
1838 /// For devices that support movements non-parallel to axes multiple
1839 /// axis events will be emitted.
1840 ///
1841 /// When applicable, for example for touch pads, the server can
1842 /// choose to emit scroll events where the motion vector is
1843 /// equivalent to a motion event vector.
1844 ///
1845 /// When applicable, a client can transform its content relative to the
1846 /// scroll distance.
1847 ///
1848 /// # Arguments
1849 ///
1850 /// - `time`: timestamp with millisecond granularity
1851 /// - `axis`: axis type
1852 /// - `value`: length of vector in surface-local coordinate space
1853 #[inline]
1854 fn handle_axis(
1855 &mut self,
1856 slf: &Rc<WlPointer>,
1857 time: u32,
1858 axis: WlPointerAxis,
1859 value: Fixed,
1860 ) {
1861 if !slf.core.forward_to_client.get() {
1862 return;
1863 }
1864 let res = slf.try_send_axis(
1865 time,
1866 axis,
1867 value,
1868 );
1869 if let Err(e) = res {
1870 log_forward("wl_pointer.axis", &e);
1871 }
1872 }
1873
1874 /// release the pointer object
1875 ///
1876 /// Using this request a client can tell the server that it is not going to
1877 /// use the pointer object anymore.
1878 ///
1879 /// This request destroys the pointer proxy object, so clients must not call
1880 /// wl_pointer_destroy() after using this request.
1881 #[inline]
1882 fn handle_release(
1883 &mut self,
1884 slf: &Rc<WlPointer>,
1885 ) {
1886 if !slf.core.forward_to_server.get() {
1887 return;
1888 }
1889 let res = slf.try_send_release(
1890 );
1891 if let Err(e) = res {
1892 log_forward("wl_pointer.release", &e);
1893 }
1894 }
1895
1896 /// end of a pointer event sequence
1897 ///
1898 /// Indicates the end of a set of events that logically belong together.
1899 /// A client is expected to accumulate the data in all events within the
1900 /// frame before proceeding.
1901 ///
1902 /// All wl_pointer events before a wl_pointer.frame event belong
1903 /// logically together. For example, in a diagonal scroll motion the
1904 /// compositor will send an optional wl_pointer.axis_source event, two
1905 /// wl_pointer.axis events (horizontal and vertical) and finally a
1906 /// wl_pointer.frame event. The client may use this information to
1907 /// calculate a diagonal vector for scrolling.
1908 ///
1909 /// When multiple wl_pointer.axis events occur within the same frame,
1910 /// the motion vector is the combined motion of all events.
1911 /// When a wl_pointer.axis and a wl_pointer.axis_stop event occur within
1912 /// the same frame, this indicates that axis movement in one axis has
1913 /// stopped but continues in the other axis.
1914 /// When multiple wl_pointer.axis_stop events occur within the same
1915 /// frame, this indicates that these axes stopped in the same instance.
1916 ///
1917 /// A wl_pointer.frame event is sent for every logical event group,
1918 /// even if the group only contains a single wl_pointer event.
1919 /// Specifically, a client may get a sequence: motion, frame, button,
1920 /// frame, axis, frame, axis_stop, frame.
1921 ///
1922 /// The wl_pointer.enter and wl_pointer.leave events are logical events
1923 /// generated by the compositor and not the hardware. These events are
1924 /// also grouped by a wl_pointer.frame. When a pointer moves from one
1925 /// surface to another, a compositor should group the
1926 /// wl_pointer.leave event within the same wl_pointer.frame.
1927 /// However, a client must not rely on wl_pointer.leave and
1928 /// wl_pointer.enter being in the same wl_pointer.frame.
1929 /// Compositor-specific policies may require the wl_pointer.leave and
1930 /// wl_pointer.enter event being split across multiple wl_pointer.frame
1931 /// groups.
1932 #[inline]
1933 fn handle_frame(
1934 &mut self,
1935 slf: &Rc<WlPointer>,
1936 ) {
1937 if !slf.core.forward_to_client.get() {
1938 return;
1939 }
1940 let res = slf.try_send_frame(
1941 );
1942 if let Err(e) = res {
1943 log_forward("wl_pointer.frame", &e);
1944 }
1945 }
1946
1947 /// axis source event
1948 ///
1949 /// Source information for scroll and other axes.
1950 ///
1951 /// This event does not occur on its own. It is sent before a
1952 /// wl_pointer.frame event and carries the source information for
1953 /// all events within that frame.
1954 ///
1955 /// The source specifies how this event was generated. If the source is
1956 /// wl_pointer.axis_source.finger, a wl_pointer.axis_stop event will be
1957 /// sent when the user lifts the finger off the device.
1958 ///
1959 /// If the source is wl_pointer.axis_source.wheel,
1960 /// wl_pointer.axis_source.wheel_tilt or
1961 /// wl_pointer.axis_source.continuous, a wl_pointer.axis_stop event may
1962 /// or may not be sent. Whether a compositor sends an axis_stop event
1963 /// for these sources is hardware-specific and implementation-dependent;
1964 /// clients must not rely on receiving an axis_stop event for these
1965 /// scroll sources and should treat scroll sequences from these scroll
1966 /// sources as unterminated by default.
1967 ///
1968 /// This event is optional. If the source is unknown for a particular
1969 /// axis event sequence, no event is sent.
1970 /// Only one wl_pointer.axis_source event is permitted per frame.
1971 ///
1972 /// The order of wl_pointer.axis_discrete and wl_pointer.axis_source is
1973 /// not guaranteed.
1974 ///
1975 /// # Arguments
1976 ///
1977 /// - `axis_source`: source of the axis event
1978 #[inline]
1979 fn handle_axis_source(
1980 &mut self,
1981 slf: &Rc<WlPointer>,
1982 axis_source: WlPointerAxisSource,
1983 ) {
1984 if !slf.core.forward_to_client.get() {
1985 return;
1986 }
1987 let res = slf.try_send_axis_source(
1988 axis_source,
1989 );
1990 if let Err(e) = res {
1991 log_forward("wl_pointer.axis_source", &e);
1992 }
1993 }
1994
1995 /// axis stop event
1996 ///
1997 /// Stop notification for scroll and other axes.
1998 ///
1999 /// For some wl_pointer.axis_source types, a wl_pointer.axis_stop event
2000 /// is sent to notify a client that the axis sequence has terminated.
2001 /// This enables the client to implement kinetic scrolling.
2002 /// See the wl_pointer.axis_source documentation for information on when
2003 /// this event may be generated.
2004 ///
2005 /// Any wl_pointer.axis events with the same axis_source after this
2006 /// event should be considered as the start of a new axis motion.
2007 ///
2008 /// The timestamp is to be interpreted identical to the timestamp in the
2009 /// wl_pointer.axis event. The timestamp value may be the same as a
2010 /// preceding wl_pointer.axis event.
2011 ///
2012 /// # Arguments
2013 ///
2014 /// - `time`: timestamp with millisecond granularity
2015 /// - `axis`: the axis stopped with this event
2016 #[inline]
2017 fn handle_axis_stop(
2018 &mut self,
2019 slf: &Rc<WlPointer>,
2020 time: u32,
2021 axis: WlPointerAxis,
2022 ) {
2023 if !slf.core.forward_to_client.get() {
2024 return;
2025 }
2026 let res = slf.try_send_axis_stop(
2027 time,
2028 axis,
2029 );
2030 if let Err(e) = res {
2031 log_forward("wl_pointer.axis_stop", &e);
2032 }
2033 }
2034
2035 /// axis click event
2036 ///
2037 /// Discrete step information for scroll and other axes.
2038 ///
2039 /// This event carries the axis value of the wl_pointer.axis event in
2040 /// discrete steps (e.g. mouse wheel clicks).
2041 ///
2042 /// This event is deprecated with wl_pointer version 8 - this event is not
2043 /// sent to clients supporting version 8 or later.
2044 ///
2045 /// This event does not occur on its own, it is coupled with a
2046 /// wl_pointer.axis event that represents this axis value on a
2047 /// continuous scale. The protocol guarantees that each axis_discrete
2048 /// event is always followed by exactly one axis event with the same
2049 /// axis number within the same wl_pointer.frame. Note that the protocol
2050 /// allows for other events to occur between the axis_discrete and
2051 /// its coupled axis event, including other axis_discrete or axis
2052 /// events. A wl_pointer.frame must not contain more than one axis_discrete
2053 /// event per axis type.
2054 ///
2055 /// This event is optional; continuous scrolling devices
2056 /// like two-finger scrolling on touchpads do not have discrete
2057 /// steps and do not generate this event.
2058 ///
2059 /// The discrete value carries the directional information. e.g. a value
2060 /// of -2 is two steps towards the negative direction of this axis.
2061 ///
2062 /// The axis number is identical to the axis number in the associated
2063 /// axis event.
2064 ///
2065 /// The order of wl_pointer.axis_discrete and wl_pointer.axis_source is
2066 /// not guaranteed.
2067 ///
2068 /// # Arguments
2069 ///
2070 /// - `axis`: axis type
2071 /// - `discrete`: number of steps
2072 #[inline]
2073 fn handle_axis_discrete(
2074 &mut self,
2075 slf: &Rc<WlPointer>,
2076 axis: WlPointerAxis,
2077 discrete: i32,
2078 ) {
2079 if !slf.core.forward_to_client.get() {
2080 return;
2081 }
2082 let res = slf.try_send_axis_discrete(
2083 axis,
2084 discrete,
2085 );
2086 if let Err(e) = res {
2087 log_forward("wl_pointer.axis_discrete", &e);
2088 }
2089 }
2090
2091 /// axis high-resolution scroll event
2092 ///
2093 /// Discrete high-resolution scroll information.
2094 ///
2095 /// This event carries high-resolution wheel scroll information,
2096 /// with each multiple of 120 representing one logical scroll step
2097 /// (a wheel detent). For example, an axis_value120 of 30 is one quarter of
2098 /// a logical scroll step in the positive direction, a value120 of
2099 /// -240 are two logical scroll steps in the negative direction within the
2100 /// same hardware event.
2101 /// Clients that rely on discrete scrolling should accumulate the
2102 /// value120 to multiples of 120 before processing the event.
2103 ///
2104 /// The value120 must not be zero.
2105 ///
2106 /// This event replaces the wl_pointer.axis_discrete event in clients
2107 /// supporting wl_pointer version 8 or later.
2108 ///
2109 /// Where a wl_pointer.axis_source event occurs in the same
2110 /// wl_pointer.frame, the axis source applies to this event.
2111 ///
2112 /// The order of wl_pointer.axis_value120 and wl_pointer.axis_source is
2113 /// not guaranteed.
2114 ///
2115 /// # Arguments
2116 ///
2117 /// - `axis`: axis type
2118 /// - `value120`: scroll distance as fraction of 120
2119 #[inline]
2120 fn handle_axis_value120(
2121 &mut self,
2122 slf: &Rc<WlPointer>,
2123 axis: WlPointerAxis,
2124 value120: i32,
2125 ) {
2126 if !slf.core.forward_to_client.get() {
2127 return;
2128 }
2129 let res = slf.try_send_axis_value120(
2130 axis,
2131 value120,
2132 );
2133 if let Err(e) = res {
2134 log_forward("wl_pointer.axis_value120", &e);
2135 }
2136 }
2137
2138 /// axis relative physical direction event
2139 ///
2140 /// Relative directional information of the entity causing the axis
2141 /// motion.
2142 ///
2143 /// For a wl_pointer.axis event, the wl_pointer.axis_relative_direction
2144 /// event specifies the movement direction of the entity causing the
2145 /// wl_pointer.axis event. For example:
2146 /// - if a user's fingers on a touchpad move down and this
2147 /// causes a wl_pointer.axis vertical_scroll down event, the physical
2148 /// direction is 'identical'
2149 /// - if a user's fingers on a touchpad move down and this causes a
2150 /// wl_pointer.axis vertical_scroll up scroll up event ('natural
2151 /// scrolling'), the physical direction is 'inverted'.
2152 ///
2153 /// A client may use this information to adjust scroll motion of
2154 /// components. Specifically, enabling natural scrolling causes the
2155 /// content to change direction compared to traditional scrolling.
2156 /// Some widgets like volume control sliders should usually match the
2157 /// physical direction regardless of whether natural scrolling is
2158 /// active. This event enables clients to match the scroll direction of
2159 /// a widget to the physical direction.
2160 ///
2161 /// This event does not occur on its own, it is coupled with a
2162 /// wl_pointer.axis event that represents this axis value.
2163 /// The protocol guarantees that each axis_relative_direction event is
2164 /// always followed by exactly one axis event with the same
2165 /// axis number within the same wl_pointer.frame. Note that the protocol
2166 /// allows for other events to occur between the axis_relative_direction
2167 /// and its coupled axis event.
2168 ///
2169 /// The axis number is identical to the axis number in the associated
2170 /// axis event.
2171 ///
2172 /// The order of wl_pointer.axis_relative_direction,
2173 /// wl_pointer.axis_discrete and wl_pointer.axis_source is not
2174 /// guaranteed.
2175 ///
2176 /// # Arguments
2177 ///
2178 /// - `axis`: axis type
2179 /// - `direction`: physical direction relative to axis motion
2180 #[inline]
2181 fn handle_axis_relative_direction(
2182 &mut self,
2183 slf: &Rc<WlPointer>,
2184 axis: WlPointerAxis,
2185 direction: WlPointerAxisRelativeDirection,
2186 ) {
2187 if !slf.core.forward_to_client.get() {
2188 return;
2189 }
2190 let res = slf.try_send_axis_relative_direction(
2191 axis,
2192 direction,
2193 );
2194 if let Err(e) = res {
2195 log_forward("wl_pointer.axis_relative_direction", &e);
2196 }
2197 }
2198}
2199
2200impl ObjectPrivate for WlPointer {
2201 fn new(state: &Rc<State>, version: u32) -> Rc<Self> {
2202 Rc::<Self>::new_cyclic(|slf| Self {
2203 core: ObjectCore::new(state, slf.clone(), ObjectInterface::WlPointer, version),
2204 handler: Default::default(),
2205 })
2206 }
2207
2208 fn delete_id(self: Rc<Self>) -> Result<(), (ObjectError, Rc<dyn Object>)> {
2209 let Some(mut handler) = self.handler.try_borrow_mut() else {
2210 return Err((ObjectError(ObjectErrorKind::HandlerBorrowed), self));
2211 };
2212 if let Some(handler) = &mut *handler {
2213 handler.delete_id(&self);
2214 } else {
2215 self.core.delete_id();
2216 }
2217 Ok(())
2218 }
2219
2220 fn handle_request(self: Rc<Self>, client: &Rc<Client>, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
2221 let Some(mut handler) = self.handler.try_borrow_mut() else {
2222 return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
2223 };
2224 let handler = &mut *handler;
2225 match msg[1] & 0xffff {
2226 0 => {
2227 let [
2228 arg0,
2229 arg1,
2230 arg2,
2231 arg3,
2232 ] = msg[2..] else {
2233 return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 24)));
2234 };
2235 let arg2 = arg2 as i32;
2236 let arg3 = arg3 as i32;
2237 #[cfg(feature = "logging")]
2238 if self.core.state.log {
2239 #[cold]
2240 fn log(state: &State, client_id: u64, id: u32, arg0: u32, arg1: u32, arg2: i32, arg3: i32) {
2241 let (millis, micros) = time_since_epoch();
2242 let prefix = &state.log_prefix;
2243 let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_pointer#{}.set_cursor(serial: {}, surface: wl_surface#{}, hotspot_x: {}, hotspot_y: {})\n", client_id, id, arg0, arg1, arg2, arg3);
2244 state.log(args);
2245 }
2246 log(&self.core.state, client.endpoint.id, msg[0], arg0, arg1, arg2, arg3);
2247 }
2248 let arg1 = if arg1 == 0 {
2249 None
2250 } else {
2251 let arg1_id = arg1;
2252 let Some(arg1) = client.endpoint.lookup(arg1_id) else {
2253 return Err(ObjectError(ObjectErrorKind::NoClientObject(client.endpoint.id, arg1_id)));
2254 };
2255 let Ok(arg1) = (arg1 as Rc<dyn Any>).downcast::<WlSurface>() else {
2256 let o = client.endpoint.lookup(arg1_id).unwrap();
2257 return Err(ObjectError(ObjectErrorKind::WrongObjectType("surface", o.core().interface, ObjectInterface::WlSurface)));
2258 };
2259 Some(arg1)
2260 };
2261 let arg1 = arg1.as_ref();
2262 if let Some(handler) = handler {
2263 (**handler).handle_set_cursor(&self, arg0, arg1, arg2, arg3);
2264 } else {
2265 DefaultHandler.handle_set_cursor(&self, arg0, arg1, arg2, arg3);
2266 }
2267 }
2268 1 => {
2269 if msg.len() != 2 {
2270 return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 8)));
2271 }
2272 #[cfg(feature = "logging")]
2273 if self.core.state.log {
2274 #[cold]
2275 fn log(state: &State, client_id: u64, id: u32) {
2276 let (millis, micros) = time_since_epoch();
2277 let prefix = &state.log_prefix;
2278 let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_pointer#{}.release()\n", client_id, id);
2279 state.log(args);
2280 }
2281 log(&self.core.state, client.endpoint.id, msg[0]);
2282 }
2283 self.core.handle_client_destroy();
2284 if let Some(handler) = handler {
2285 (**handler).handle_release(&self);
2286 } else {
2287 DefaultHandler.handle_release(&self);
2288 }
2289 }
2290 n => {
2291 let _ = client;
2292 let _ = msg;
2293 let _ = fds;
2294 let _ = handler;
2295 return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
2296 }
2297 }
2298 Ok(())
2299 }
2300
2301 fn handle_event(self: Rc<Self>, server: &Endpoint, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
2302 let Some(mut handler) = self.handler.try_borrow_mut() else {
2303 return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
2304 };
2305 let handler = &mut *handler;
2306 match msg[1] & 0xffff {
2307 0 => {
2308 let [
2309 arg0,
2310 arg1,
2311 arg2,
2312 arg3,
2313 ] = msg[2..] else {
2314 return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 24)));
2315 };
2316 let arg2 = Fixed::from_wire(arg2 as i32);
2317 let arg3 = Fixed::from_wire(arg3 as i32);
2318 #[cfg(feature = "logging")]
2319 if self.core.state.log {
2320 #[cold]
2321 fn log(state: &State, id: u32, arg0: u32, arg1: u32, arg2: Fixed, arg3: Fixed) {
2322 let (millis, micros) = time_since_epoch();
2323 let prefix = &state.log_prefix;
2324 let args = format_args!("[{millis:7}.{micros:03}] {prefix}server -> wl_pointer#{}.enter(serial: {}, surface: wl_surface#{}, surface_x: {}, surface_y: {})\n", id, arg0, arg1, arg2, arg3);
2325 state.log(args);
2326 }
2327 log(&self.core.state, msg[0], arg0, arg1, arg2, arg3);
2328 }
2329 let arg1_id = arg1;
2330 let Some(arg1) = server.lookup(arg1_id) else {
2331 return Err(ObjectError(ObjectErrorKind::NoServerObject(arg1_id)));
2332 };
2333 let Ok(arg1) = (arg1 as Rc<dyn Any>).downcast::<WlSurface>() else {
2334 let o = server.lookup(arg1_id).unwrap();
2335 return Err(ObjectError(ObjectErrorKind::WrongObjectType("surface", o.core().interface, ObjectInterface::WlSurface)));
2336 };
2337 let arg1 = &arg1;
2338 if let Some(handler) = handler {
2339 (**handler).handle_enter(&self, arg0, arg1, arg2, arg3);
2340 } else {
2341 DefaultHandler.handle_enter(&self, arg0, arg1, arg2, arg3);
2342 }
2343 }
2344 1 => {
2345 let [
2346 arg0,
2347 arg1,
2348 ] = msg[2..] else {
2349 return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 16)));
2350 };
2351 #[cfg(feature = "logging")]
2352 if self.core.state.log {
2353 #[cold]
2354 fn log(state: &State, id: u32, arg0: u32, arg1: u32) {
2355 let (millis, micros) = time_since_epoch();
2356 let prefix = &state.log_prefix;
2357 let args = format_args!("[{millis:7}.{micros:03}] {prefix}server -> wl_pointer#{}.leave(serial: {}, surface: wl_surface#{})\n", id, arg0, arg1);
2358 state.log(args);
2359 }
2360 log(&self.core.state, msg[0], arg0, arg1);
2361 }
2362 let arg1_id = arg1;
2363 let Some(arg1) = server.lookup(arg1_id) else {
2364 return Err(ObjectError(ObjectErrorKind::NoServerObject(arg1_id)));
2365 };
2366 let Ok(arg1) = (arg1 as Rc<dyn Any>).downcast::<WlSurface>() else {
2367 let o = server.lookup(arg1_id).unwrap();
2368 return Err(ObjectError(ObjectErrorKind::WrongObjectType("surface", o.core().interface, ObjectInterface::WlSurface)));
2369 };
2370 let arg1 = &arg1;
2371 if let Some(handler) = handler {
2372 (**handler).handle_leave(&self, arg0, arg1);
2373 } else {
2374 DefaultHandler.handle_leave(&self, arg0, arg1);
2375 }
2376 }
2377 2 => {
2378 let [
2379 arg0,
2380 arg1,
2381 arg2,
2382 ] = msg[2..] else {
2383 return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 20)));
2384 };
2385 let arg1 = Fixed::from_wire(arg1 as i32);
2386 let arg2 = Fixed::from_wire(arg2 as i32);
2387 #[cfg(feature = "logging")]
2388 if self.core.state.log {
2389 #[cold]
2390 fn log(state: &State, id: u32, arg0: u32, arg1: Fixed, arg2: Fixed) {
2391 let (millis, micros) = time_since_epoch();
2392 let prefix = &state.log_prefix;
2393 let args = format_args!("[{millis:7}.{micros:03}] {prefix}server -> wl_pointer#{}.motion(time: {}, surface_x: {}, surface_y: {})\n", id, arg0, arg1, arg2);
2394 state.log(args);
2395 }
2396 log(&self.core.state, msg[0], arg0, arg1, arg2);
2397 }
2398 if let Some(handler) = handler {
2399 (**handler).handle_motion(&self, arg0, arg1, arg2);
2400 } else {
2401 DefaultHandler.handle_motion(&self, arg0, arg1, arg2);
2402 }
2403 }
2404 3 => {
2405 let [
2406 arg0,
2407 arg1,
2408 arg2,
2409 arg3,
2410 ] = msg[2..] else {
2411 return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 24)));
2412 };
2413 let arg3 = WlPointerButtonState(arg3);
2414 #[cfg(feature = "logging")]
2415 if self.core.state.log {
2416 #[cold]
2417 fn log(state: &State, id: u32, arg0: u32, arg1: u32, arg2: u32, arg3: WlPointerButtonState) {
2418 let (millis, micros) = time_since_epoch();
2419 let prefix = &state.log_prefix;
2420 let args = format_args!("[{millis:7}.{micros:03}] {prefix}server -> wl_pointer#{}.button(serial: {}, time: {}, button: {}, state: {:?})\n", id, arg0, arg1, arg2, arg3);
2421 state.log(args);
2422 }
2423 log(&self.core.state, msg[0], arg0, arg1, arg2, arg3);
2424 }
2425 if let Some(handler) = handler {
2426 (**handler).handle_button(&self, arg0, arg1, arg2, arg3);
2427 } else {
2428 DefaultHandler.handle_button(&self, arg0, arg1, arg2, arg3);
2429 }
2430 }
2431 4 => {
2432 let [
2433 arg0,
2434 arg1,
2435 arg2,
2436 ] = msg[2..] else {
2437 return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 20)));
2438 };
2439 let arg1 = WlPointerAxis(arg1);
2440 let arg2 = Fixed::from_wire(arg2 as i32);
2441 #[cfg(feature = "logging")]
2442 if self.core.state.log {
2443 #[cold]
2444 fn log(state: &State, id: u32, arg0: u32, arg1: WlPointerAxis, arg2: Fixed) {
2445 let (millis, micros) = time_since_epoch();
2446 let prefix = &state.log_prefix;
2447 let args = format_args!("[{millis:7}.{micros:03}] {prefix}server -> wl_pointer#{}.axis(time: {}, axis: {:?}, value: {})\n", id, arg0, arg1, arg2);
2448 state.log(args);
2449 }
2450 log(&self.core.state, msg[0], arg0, arg1, arg2);
2451 }
2452 if let Some(handler) = handler {
2453 (**handler).handle_axis(&self, arg0, arg1, arg2);
2454 } else {
2455 DefaultHandler.handle_axis(&self, arg0, arg1, arg2);
2456 }
2457 }
2458 5 => {
2459 if msg.len() != 2 {
2460 return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 8)));
2461 }
2462 #[cfg(feature = "logging")]
2463 if self.core.state.log {
2464 #[cold]
2465 fn log(state: &State, id: u32) {
2466 let (millis, micros) = time_since_epoch();
2467 let prefix = &state.log_prefix;
2468 let args = format_args!("[{millis:7}.{micros:03}] {prefix}server -> wl_pointer#{}.frame()\n", id);
2469 state.log(args);
2470 }
2471 log(&self.core.state, msg[0]);
2472 }
2473 if let Some(handler) = handler {
2474 (**handler).handle_frame(&self);
2475 } else {
2476 DefaultHandler.handle_frame(&self);
2477 }
2478 }
2479 6 => {
2480 let [
2481 arg0,
2482 ] = msg[2..] else {
2483 return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
2484 };
2485 let arg0 = WlPointerAxisSource(arg0);
2486 #[cfg(feature = "logging")]
2487 if self.core.state.log {
2488 #[cold]
2489 fn log(state: &State, id: u32, arg0: WlPointerAxisSource) {
2490 let (millis, micros) = time_since_epoch();
2491 let prefix = &state.log_prefix;
2492 let args = format_args!("[{millis:7}.{micros:03}] {prefix}server -> wl_pointer#{}.axis_source(axis_source: {:?})\n", id, arg0);
2493 state.log(args);
2494 }
2495 log(&self.core.state, msg[0], arg0);
2496 }
2497 if let Some(handler) = handler {
2498 (**handler).handle_axis_source(&self, arg0);
2499 } else {
2500 DefaultHandler.handle_axis_source(&self, arg0);
2501 }
2502 }
2503 7 => {
2504 let [
2505 arg0,
2506 arg1,
2507 ] = msg[2..] else {
2508 return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 16)));
2509 };
2510 let arg1 = WlPointerAxis(arg1);
2511 #[cfg(feature = "logging")]
2512 if self.core.state.log {
2513 #[cold]
2514 fn log(state: &State, id: u32, arg0: u32, arg1: WlPointerAxis) {
2515 let (millis, micros) = time_since_epoch();
2516 let prefix = &state.log_prefix;
2517 let args = format_args!("[{millis:7}.{micros:03}] {prefix}server -> wl_pointer#{}.axis_stop(time: {}, axis: {:?})\n", id, arg0, arg1);
2518 state.log(args);
2519 }
2520 log(&self.core.state, msg[0], arg0, arg1);
2521 }
2522 if let Some(handler) = handler {
2523 (**handler).handle_axis_stop(&self, arg0, arg1);
2524 } else {
2525 DefaultHandler.handle_axis_stop(&self, arg0, arg1);
2526 }
2527 }
2528 8 => {
2529 let [
2530 arg0,
2531 arg1,
2532 ] = msg[2..] else {
2533 return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 16)));
2534 };
2535 let arg0 = WlPointerAxis(arg0);
2536 let arg1 = arg1 as i32;
2537 #[cfg(feature = "logging")]
2538 if self.core.state.log {
2539 #[cold]
2540 fn log(state: &State, id: u32, arg0: WlPointerAxis, arg1: i32) {
2541 let (millis, micros) = time_since_epoch();
2542 let prefix = &state.log_prefix;
2543 let args = format_args!("[{millis:7}.{micros:03}] {prefix}server -> wl_pointer#{}.axis_discrete(axis: {:?}, discrete: {})\n", id, arg0, arg1);
2544 state.log(args);
2545 }
2546 log(&self.core.state, msg[0], arg0, arg1);
2547 }
2548 if let Some(handler) = handler {
2549 (**handler).handle_axis_discrete(&self, arg0, arg1);
2550 } else {
2551 DefaultHandler.handle_axis_discrete(&self, arg0, arg1);
2552 }
2553 }
2554 9 => {
2555 let [
2556 arg0,
2557 arg1,
2558 ] = msg[2..] else {
2559 return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 16)));
2560 };
2561 let arg0 = WlPointerAxis(arg0);
2562 let arg1 = arg1 as i32;
2563 #[cfg(feature = "logging")]
2564 if self.core.state.log {
2565 #[cold]
2566 fn log(state: &State, id: u32, arg0: WlPointerAxis, arg1: i32) {
2567 let (millis, micros) = time_since_epoch();
2568 let prefix = &state.log_prefix;
2569 let args = format_args!("[{millis:7}.{micros:03}] {prefix}server -> wl_pointer#{}.axis_value120(axis: {:?}, value120: {})\n", id, arg0, arg1);
2570 state.log(args);
2571 }
2572 log(&self.core.state, msg[0], arg0, arg1);
2573 }
2574 if let Some(handler) = handler {
2575 (**handler).handle_axis_value120(&self, arg0, arg1);
2576 } else {
2577 DefaultHandler.handle_axis_value120(&self, arg0, arg1);
2578 }
2579 }
2580 10 => {
2581 let [
2582 arg0,
2583 arg1,
2584 ] = msg[2..] else {
2585 return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 16)));
2586 };
2587 let arg0 = WlPointerAxis(arg0);
2588 let arg1 = WlPointerAxisRelativeDirection(arg1);
2589 #[cfg(feature = "logging")]
2590 if self.core.state.log {
2591 #[cold]
2592 fn log(state: &State, id: u32, arg0: WlPointerAxis, arg1: WlPointerAxisRelativeDirection) {
2593 let (millis, micros) = time_since_epoch();
2594 let prefix = &state.log_prefix;
2595 let args = format_args!("[{millis:7}.{micros:03}] {prefix}server -> wl_pointer#{}.axis_relative_direction(axis: {:?}, direction: {:?})\n", id, arg0, arg1);
2596 state.log(args);
2597 }
2598 log(&self.core.state, msg[0], arg0, arg1);
2599 }
2600 if let Some(handler) = handler {
2601 (**handler).handle_axis_relative_direction(&self, arg0, arg1);
2602 } else {
2603 DefaultHandler.handle_axis_relative_direction(&self, arg0, arg1);
2604 }
2605 }
2606 n => {
2607 let _ = server;
2608 let _ = msg;
2609 let _ = fds;
2610 let _ = handler;
2611 return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
2612 }
2613 }
2614 Ok(())
2615 }
2616
2617 fn get_request_name(&self, id: u32) -> Option<&'static str> {
2618 let name = match id {
2619 0 => "set_cursor",
2620 1 => "release",
2621 _ => return None,
2622 };
2623 Some(name)
2624 }
2625
2626 fn get_event_name(&self, id: u32) -> Option<&'static str> {
2627 let name = match id {
2628 0 => "enter",
2629 1 => "leave",
2630 2 => "motion",
2631 3 => "button",
2632 4 => "axis",
2633 5 => "frame",
2634 6 => "axis_source",
2635 7 => "axis_stop",
2636 8 => "axis_discrete",
2637 9 => "axis_value120",
2638 10 => "axis_relative_direction",
2639 _ => return None,
2640 };
2641 Some(name)
2642 }
2643}
2644
2645impl Object for WlPointer {
2646 fn core(&self) -> &ObjectCore {
2647 &self.core
2648 }
2649
2650 fn unset_handler(&self) {
2651 self.handler.set(None);
2652 }
2653
2654 fn get_handler_any_ref(&self) -> Result<HandlerRef<'_, dyn Any>, HandlerAccessError> {
2655 let borrowed = self.handler.try_borrow().ok_or(HandlerAccessError::AlreadyBorrowed)?;
2656 if borrowed.is_none() {
2657 return Err(HandlerAccessError::NoHandler);
2658 }
2659 Ok(HandlerRef::map(borrowed, |handler| &**handler.as_ref().unwrap() as &dyn Any))
2660 }
2661
2662 fn get_handler_any_mut(&self) -> Result<HandlerMut<'_, dyn Any>, HandlerAccessError> {
2663 let borrowed = self.handler.try_borrow_mut().ok_or(HandlerAccessError::AlreadyBorrowed)?;
2664 if borrowed.is_none() {
2665 return Err(HandlerAccessError::NoHandler);
2666 }
2667 Ok(HandlerMut::map(borrowed, |handler| &mut **handler.as_mut().unwrap() as &mut dyn Any))
2668 }
2669}
2670
2671impl WlPointer {
2672 /// Since when the error.role enum variant is available.
2673 pub const ENM__ERROR_ROLE__SINCE: u32 = 1;
2674
2675 /// Since when the button_state.released enum variant is available.
2676 pub const ENM__BUTTON_STATE_RELEASED__SINCE: u32 = 1;
2677 /// Since when the button_state.pressed enum variant is available.
2678 pub const ENM__BUTTON_STATE_PRESSED__SINCE: u32 = 1;
2679
2680 /// Since when the axis.vertical_scroll enum variant is available.
2681 pub const ENM__AXIS_VERTICAL_SCROLL__SINCE: u32 = 1;
2682 /// Since when the axis.horizontal_scroll enum variant is available.
2683 pub const ENM__AXIS_HORIZONTAL_SCROLL__SINCE: u32 = 1;
2684
2685 /// Since when the axis_source.wheel enum variant is available.
2686 pub const ENM__AXIS_SOURCE_WHEEL__SINCE: u32 = 1;
2687 /// Since when the axis_source.finger enum variant is available.
2688 pub const ENM__AXIS_SOURCE_FINGER__SINCE: u32 = 1;
2689 /// Since when the axis_source.continuous enum variant is available.
2690 pub const ENM__AXIS_SOURCE_CONTINUOUS__SINCE: u32 = 1;
2691 /// Since when the axis_source.wheel_tilt enum variant is available.
2692 pub const ENM__AXIS_SOURCE_WHEEL_TILT__SINCE: u32 = 6;
2693
2694 /// Since when the axis_relative_direction.identical enum variant is available.
2695 pub const ENM__AXIS_RELATIVE_DIRECTION_IDENTICAL__SINCE: u32 = 1;
2696 /// Since when the axis_relative_direction.inverted enum variant is available.
2697 pub const ENM__AXIS_RELATIVE_DIRECTION_INVERTED__SINCE: u32 = 1;
2698}
2699
2700#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
2701pub struct WlPointerError(pub u32);
2702
2703impl WlPointerError {
2704 /// given wl_surface has another role
2705 pub const ROLE: Self = Self(0);
2706}
2707
2708impl Debug for WlPointerError {
2709 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
2710 let name = match *self {
2711 Self::ROLE => "ROLE",
2712 _ => return Debug::fmt(&self.0, f),
2713 };
2714 f.write_str(name)
2715 }
2716}
2717
2718/// physical button state
2719///
2720/// Describes the physical state of a button that produced the button
2721/// event.
2722#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
2723pub struct WlPointerButtonState(pub u32);
2724
2725impl WlPointerButtonState {
2726 /// the button is not pressed
2727 pub const RELEASED: Self = Self(0);
2728
2729 /// the button is pressed
2730 pub const PRESSED: Self = Self(1);
2731}
2732
2733impl Debug for WlPointerButtonState {
2734 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
2735 let name = match *self {
2736 Self::RELEASED => "RELEASED",
2737 Self::PRESSED => "PRESSED",
2738 _ => return Debug::fmt(&self.0, f),
2739 };
2740 f.write_str(name)
2741 }
2742}
2743
2744/// axis types
2745///
2746/// Describes the axis types of scroll events.
2747#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
2748pub struct WlPointerAxis(pub u32);
2749
2750impl WlPointerAxis {
2751 /// vertical axis
2752 pub const VERTICAL_SCROLL: Self = Self(0);
2753
2754 /// horizontal axis
2755 pub const HORIZONTAL_SCROLL: Self = Self(1);
2756}
2757
2758impl Debug for WlPointerAxis {
2759 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
2760 let name = match *self {
2761 Self::VERTICAL_SCROLL => "VERTICAL_SCROLL",
2762 Self::HORIZONTAL_SCROLL => "HORIZONTAL_SCROLL",
2763 _ => return Debug::fmt(&self.0, f),
2764 };
2765 f.write_str(name)
2766 }
2767}
2768
2769/// axis source types
2770///
2771/// Describes the source types for axis events. This indicates to the
2772/// client how an axis event was physically generated; a client may
2773/// adjust the user interface accordingly. For example, scroll events
2774/// from a "finger" source may be in a smooth coordinate space with
2775/// kinetic scrolling whereas a "wheel" source may be in discrete steps
2776/// of a number of lines.
2777///
2778/// The "continuous" axis source is a device generating events in a
2779/// continuous coordinate space, but using something other than a
2780/// finger. One example for this source is button-based scrolling where
2781/// the vertical motion of a device is converted to scroll events while
2782/// a button is held down.
2783///
2784/// The "wheel tilt" axis source indicates that the actual device is a
2785/// wheel but the scroll event is not caused by a rotation but a
2786/// (usually sideways) tilt of the wheel.
2787#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
2788pub struct WlPointerAxisSource(pub u32);
2789
2790impl WlPointerAxisSource {
2791 /// a physical wheel rotation
2792 pub const WHEEL: Self = Self(0);
2793
2794 /// finger on a touch surface
2795 pub const FINGER: Self = Self(1);
2796
2797 /// continuous coordinate space
2798 pub const CONTINUOUS: Self = Self(2);
2799
2800 /// a physical wheel tilt
2801 pub const WHEEL_TILT: Self = Self(3);
2802}
2803
2804impl Debug for WlPointerAxisSource {
2805 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
2806 let name = match *self {
2807 Self::WHEEL => "WHEEL",
2808 Self::FINGER => "FINGER",
2809 Self::CONTINUOUS => "CONTINUOUS",
2810 Self::WHEEL_TILT => "WHEEL_TILT",
2811 _ => return Debug::fmt(&self.0, f),
2812 };
2813 f.write_str(name)
2814 }
2815}
2816
2817/// axis relative direction
2818///
2819/// This specifies the direction of the physical motion that caused a
2820/// wl_pointer.axis event, relative to the wl_pointer.axis direction.
2821#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
2822pub struct WlPointerAxisRelativeDirection(pub u32);
2823
2824impl WlPointerAxisRelativeDirection {
2825 /// physical motion matches axis direction
2826 pub const IDENTICAL: Self = Self(0);
2827
2828 /// physical motion is the inverse of the axis direction
2829 pub const INVERTED: Self = Self(1);
2830}
2831
2832impl Debug for WlPointerAxisRelativeDirection {
2833 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
2834 let name = match *self {
2835 Self::IDENTICAL => "IDENTICAL",
2836 Self::INVERTED => "INVERTED",
2837 _ => return Debug::fmt(&self.0, f),
2838 };
2839 f.write_str(name)
2840 }
2841}