poll_integration/common/protocols/tablet_v2/zwp_tablet_pad_ring_v2.rs
1//! pad ring
2//!
3//! A circular interaction area, such as the touch ring on the Wacom Intuos
4//! Pro series tablets.
5//!
6//! Events on a ring are logically grouped by the wl_tablet_pad_ring.frame
7//! event.
8
9use {super::super::all_types::*, ::wl_client::builder::prelude::*};
10
11static INTERFACE: wl_interface = wl_interface {
12 name: c"zwp_tablet_pad_ring_v2".as_ptr(),
13 version: 1,
14 method_count: 2,
15 methods: {
16 static MESSAGES: [wl_message; 2] = [
17 wl_message {
18 name: c"set_feedback".as_ptr(),
19 signature: c"su".as_ptr(),
20 types: {
21 static TYPES: [Option<&'static wl_interface>; 2] = [None, None];
22 TYPES.as_ptr().cast()
23 },
24 },
25 wl_message {
26 name: c"destroy".as_ptr(),
27 signature: c"".as_ptr(),
28 types: {
29 static TYPES: [Option<&'static wl_interface>; 0] = [];
30 TYPES.as_ptr().cast()
31 },
32 },
33 ];
34 MESSAGES.as_ptr()
35 },
36 event_count: 4,
37 events: {
38 static MESSAGES: [wl_message; 4] = [
39 wl_message {
40 name: c"source".as_ptr(),
41 signature: c"u".as_ptr(),
42 types: {
43 static TYPES: [Option<&'static wl_interface>; 1] = [None];
44 TYPES.as_ptr().cast()
45 },
46 },
47 wl_message {
48 name: c"angle".as_ptr(),
49 signature: c"f".as_ptr(),
50 types: {
51 static TYPES: [Option<&'static wl_interface>; 1] = [None];
52 TYPES.as_ptr().cast()
53 },
54 },
55 wl_message {
56 name: c"stop".as_ptr(),
57 signature: c"".as_ptr(),
58 types: {
59 static TYPES: [Option<&'static wl_interface>; 0] = [];
60 TYPES.as_ptr().cast()
61 },
62 },
63 wl_message {
64 name: c"frame".as_ptr(),
65 signature: c"u".as_ptr(),
66 types: {
67 static TYPES: [Option<&'static wl_interface>; 1] = [None];
68 TYPES.as_ptr().cast()
69 },
70 },
71 ];
72 MESSAGES.as_ptr()
73 },
74};
75
76/// An owned zwp_tablet_pad_ring_v2 proxy.
77///
78/// See the documentation of [the module][self] for the interface description.
79#[derive(Clone, Eq, PartialEq)]
80#[repr(transparent)]
81pub struct ZwpTabletPadRingV2 {
82 /// This proxy has the interface INTERFACE.
83 proxy: UntypedOwnedProxy,
84}
85
86/// A borrowed zwp_tablet_pad_ring_v2 proxy.
87///
88/// See the documentation of [the module][self] for the interface description.
89#[derive(Eq, PartialEq)]
90#[repr(transparent)]
91pub struct ZwpTabletPadRingV2Ref {
92 /// This proxy has the interface INTERFACE.
93 proxy: UntypedBorrowedProxy,
94}
95
96// SAFETY: ZwpTabletPadRingV2 is a transparent wrapper around UntypedOwnedProxy
97unsafe impl UntypedOwnedProxyWrapper for ZwpTabletPadRingV2 {}
98
99// SAFETY: - INTERFACE is a valid wl_interface
100// - The only invariant is that self.proxy has a compatible interface
101unsafe impl OwnedProxy for ZwpTabletPadRingV2 {
102 const INTERFACE: &'static str = "zwp_tablet_pad_ring_v2";
103 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
104 const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
105 private::EventHandler(private::NoOpEventHandler);
106 const MAX_VERSION: u32 = 1;
107
108 type Borrowed = ZwpTabletPadRingV2Ref;
109 type Api = private::ProxyApi;
110 type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
111}
112
113// SAFETY: ZwpTabletPadRingV2Ref is a transparent wrapper around UntypedBorrowedProxy
114unsafe impl UntypedBorrowedProxyWrapper for ZwpTabletPadRingV2Ref {}
115
116// SAFETY: - The only invariant is that self.proxy has a compatible interface
117unsafe impl BorrowedProxy for ZwpTabletPadRingV2Ref {
118 type Owned = ZwpTabletPadRingV2;
119}
120
121impl Deref for ZwpTabletPadRingV2 {
122 type Target = ZwpTabletPadRingV2Ref;
123
124 fn deref(&self) -> &Self::Target {
125 proxy::low_level::deref(self)
126 }
127}
128
129mod private {
130 pub struct ProxyApi;
131
132 #[allow(dead_code)]
133 pub struct EventHandler<H>(pub(super) H);
134
135 #[allow(dead_code)]
136 pub struct NoOpEventHandler;
137}
138
139impl Debug for ZwpTabletPadRingV2 {
140 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
141 write!(f, "zwp_tablet_pad_ring_v2#{}", self.proxy.id())
142 }
143}
144
145impl Debug for ZwpTabletPadRingV2Ref {
146 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
147 write!(f, "zwp_tablet_pad_ring_v2#{}", self.proxy.id())
148 }
149}
150
151impl PartialEq<ZwpTabletPadRingV2Ref> for ZwpTabletPadRingV2 {
152 fn eq(&self, other: &ZwpTabletPadRingV2Ref) -> bool {
153 self.proxy == other.proxy
154 }
155}
156
157impl PartialEq<ZwpTabletPadRingV2> for ZwpTabletPadRingV2Ref {
158 fn eq(&self, other: &ZwpTabletPadRingV2) -> bool {
159 self.proxy == other.proxy
160 }
161}
162
163#[allow(dead_code)]
164impl ZwpTabletPadRingV2 {
165 /// Since when the destroy request is available.
166 #[allow(dead_code)]
167 pub const REQ__DESTROY__SINCE: u32 = 1;
168
169 /// destroy the ring object
170 ///
171 /// This destroys the client's resource for this ring object.
172 #[inline]
173 pub fn destroy(&self) {
174 let mut args = [];
175 // SAFETY: - self.proxy has the interface INTERFACE
176 // - 1 < INTERFACE.method_count = 2
177 // - the request signature is ``
178 unsafe {
179 self.proxy.send_destructor(1, &mut args);
180 }
181 }
182}
183
184#[allow(dead_code)]
185impl ZwpTabletPadRingV2Ref {
186 /// set compositor feedback
187 ///
188 /// Request that the compositor use the provided feedback string
189 /// associated with this ring. This request should be issued immediately
190 /// after a wp_tablet_pad_group.mode_switch event from the corresponding
191 /// group is received, or whenever the ring is mapped to a different
192 /// action. See wp_tablet_pad_group.mode_switch for more details.
193 ///
194 /// Clients are encouraged to provide context-aware descriptions for
195 /// the actions associated with the ring; compositors may use this
196 /// information to offer visual feedback about the button layout
197 /// (eg. on-screen displays).
198 ///
199 /// The provided string 'description' is a UTF-8 encoded string to be
200 /// associated with this ring, and is considered user-visible; general
201 /// internationalization rules apply.
202 ///
203 /// The serial argument will be that of the last
204 /// wp_tablet_pad_group.mode_switch event received for the group of this
205 /// ring. Requests providing other serials than the most recent one will be
206 /// ignored.
207 ///
208 /// # Arguments
209 ///
210 /// - `description`: ring description
211 /// - `serial`: serial of the mode switch event
212 #[inline]
213 pub fn set_feedback(&self, description: &str, serial: u32) {
214 let (arg0, arg1) = (description, serial);
215 with_cstr_cache(|cache| {
216 let str0_offset = cache.len();
217 cache.extend_from_slice(arg0.as_bytes());
218 cache.push(0);
219 let str0 = cache[str0_offset..].as_ptr().cast();
220 let mut args = [wl_argument { s: str0 }, wl_argument { u: arg1 }];
221 // SAFETY: - self.proxy has the interface INTERFACE
222 // - 0 < INTERFACE.method_count = 2
223 // - the request signature is `su`
224 unsafe {
225 self.proxy.send_request(0, &mut args);
226 }
227 })
228 }
229}
230
231impl ZwpTabletPadRingV2 {
232 /// Since when the source event is available.
233 #[allow(dead_code)]
234 pub const EVT__SOURCE__SINCE: u32 = 1;
235
236 /// Since when the angle event is available.
237 #[allow(dead_code)]
238 pub const EVT__ANGLE__SINCE: u32 = 1;
239
240 /// Since when the stop event is available.
241 #[allow(dead_code)]
242 pub const EVT__STOP__SINCE: u32 = 1;
243
244 /// Since when the frame event is available.
245 #[allow(dead_code)]
246 pub const EVT__FRAME__SINCE: u32 = 1;
247}
248
249/// An event handler for [ZwpTabletPadRingV2] proxies.
250#[allow(dead_code)]
251pub trait ZwpTabletPadRingV2EventHandler {
252 /// ring event source
253 ///
254 /// Source information for ring events.
255 ///
256 /// This event does not occur on its own. It is sent before a
257 /// wp_tablet_pad_ring.frame event and carries the source information
258 /// for all events within that frame.
259 ///
260 /// The source specifies how this event was generated. If the source is
261 /// wp_tablet_pad_ring.source.finger, a wp_tablet_pad_ring.stop event
262 /// will be sent when the user lifts the finger off the device.
263 ///
264 /// This event is optional. If the source is unknown for an interaction,
265 /// no event is sent.
266 ///
267 /// # Arguments
268 ///
269 /// - `source`: the event source
270 #[inline]
271 fn source(&self, _slf: &ZwpTabletPadRingV2Ref, source: ZwpTabletPadRingV2Source) {
272 let _ = source;
273 }
274
275 /// angle changed
276 ///
277 /// Sent whenever the angle on a ring changes.
278 ///
279 /// The angle is provided in degrees clockwise from the logical
280 /// north of the ring in the pad's current rotation.
281 ///
282 /// # Arguments
283 ///
284 /// - `degrees`: the current angle in degrees
285 #[inline]
286 fn angle(&self, _slf: &ZwpTabletPadRingV2Ref, degrees: Fixed) {
287 let _ = degrees;
288 }
289
290 /// interaction stopped
291 ///
292 /// Stop notification for ring events.
293 ///
294 /// For some wp_tablet_pad_ring.source types, a wp_tablet_pad_ring.stop
295 /// event is sent to notify a client that the interaction with the ring
296 /// has terminated. This enables the client to implement kinetic scrolling.
297 /// See the wp_tablet_pad_ring.source documentation for information on
298 /// when this event may be generated.
299 ///
300 /// Any wp_tablet_pad_ring.angle events with the same source after this
301 /// event should be considered as the start of a new interaction.
302 #[inline]
303 fn stop(&self, _slf: &ZwpTabletPadRingV2Ref) {}
304
305 /// end of a ring event sequence
306 ///
307 /// Indicates the end of a set of ring events that logically belong
308 /// together. A client is expected to accumulate the data in all events
309 /// within the frame before proceeding.
310 ///
311 /// All wp_tablet_pad_ring events before a wp_tablet_pad_ring.frame event belong
312 /// logically together. For example, on termination of a finger interaction
313 /// on a ring the compositor will send a wp_tablet_pad_ring.source event,
314 /// a wp_tablet_pad_ring.stop event and a wp_tablet_pad_ring.frame event.
315 ///
316 /// A wp_tablet_pad_ring.frame event is sent for every logical event
317 /// group, even if the group only contains a single wp_tablet_pad_ring
318 /// event. Specifically, a client may get a sequence: angle, frame,
319 /// angle, frame, etc.
320 ///
321 /// # Arguments
322 ///
323 /// - `time`: timestamp with millisecond granularity
324 #[inline]
325 fn frame(&self, _slf: &ZwpTabletPadRingV2Ref, time: u32) {
326 let _ = time;
327 }
328}
329
330impl ZwpTabletPadRingV2EventHandler for private::NoOpEventHandler {}
331
332// SAFETY: INTERFACE is a valid wl_interface
333unsafe impl<H> EventHandler for private::EventHandler<H>
334where
335 H: ZwpTabletPadRingV2EventHandler,
336{
337 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
338
339 #[allow(unused_variables)]
340 unsafe fn handle_event(
341 &self,
342 queue: &Queue,
343 slf: &UntypedBorrowedProxy,
344 opcode: u32,
345 args: *mut wl_argument,
346 ) {
347 // SAFETY: This function required that slf has the interface INTERFACE
348 let slf = unsafe { proxy::low_level::from_untyped_borrowed::<ZwpTabletPadRingV2Ref>(slf) };
349 match opcode {
350 0 => {
351 // SAFETY: INTERFACE requires that there are 1 arguments
352 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
353 // SAFETY: - INTERFACE requires that args[0] contains a uint
354 let arg0 = unsafe { ZwpTabletPadRingV2Source(args[0].u) };
355 self.0.source(slf, arg0);
356 }
357 1 => {
358 // SAFETY: INTERFACE requires that there are 1 arguments
359 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
360 // SAFETY: - INTERFACE requires that args[0] contains a fixed
361 let arg0 = unsafe { Fixed::from_wire(args[0].f) };
362 self.0.angle(slf, arg0);
363 }
364 2 => {
365 self.0.stop(slf);
366 }
367 3 => {
368 // SAFETY: INTERFACE requires that there are 1 arguments
369 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
370 // SAFETY: - INTERFACE requires that args[0] contains a uint
371 let arg0 = unsafe { args[0].u };
372 self.0.frame(slf, arg0);
373 }
374 _ => {
375 invalid_opcode("zwp_tablet_pad_ring_v2", opcode);
376 }
377 }
378 }
379}
380
381impl<H> CreateEventHandler<H> for private::ProxyApi
382where
383 H: ZwpTabletPadRingV2EventHandler,
384{
385 type EventHandler = private::EventHandler<H>;
386
387 #[inline]
388 fn create_event_handler(handler: H) -> Self::EventHandler {
389 private::EventHandler(handler)
390 }
391}
392
393impl ZwpTabletPadRingV2 {
394 /// Since when the source.finger enum variant is available.
395 #[allow(dead_code)]
396 pub const ENM__SOURCE_FINGER__SINCE: u32 = 1;
397}
398
399/// ring axis source
400///
401/// Describes the source types for ring events. This indicates to the
402/// client how a ring event was physically generated; a client may
403/// adjust the user interface accordingly. For example, events
404/// from a "finger" source may trigger kinetic scrolling.
405#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
406#[allow(dead_code)]
407pub struct ZwpTabletPadRingV2Source(pub u32);
408
409impl ZwpTabletPadRingV2Source {
410 /// finger
411 #[allow(dead_code)]
412 pub const FINGER: Self = Self(1);
413}
414
415impl Debug for ZwpTabletPadRingV2Source {
416 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
417 let name = match *self {
418 Self::FINGER => "FINGER",
419 _ => return Debug::fmt(&self.0, f),
420 };
421 f.write_str(name)
422 }
423}
424
425/// Functional event handlers.
426pub mod event_handlers {
427 use super::*;
428
429 /// Event handler for source events.
430 pub struct Source<F>(F);
431 impl<F> ZwpTabletPadRingV2EventHandler for Source<F>
432 where
433 F: Fn(&ZwpTabletPadRingV2Ref, ZwpTabletPadRingV2Source),
434 {
435 #[inline]
436 fn source(&self, _slf: &ZwpTabletPadRingV2Ref, source: ZwpTabletPadRingV2Source) {
437 self.0(_slf, source)
438 }
439 }
440
441 /// Event handler for angle events.
442 pub struct Angle<F>(F);
443 impl<F> ZwpTabletPadRingV2EventHandler for Angle<F>
444 where
445 F: Fn(&ZwpTabletPadRingV2Ref, Fixed),
446 {
447 #[inline]
448 fn angle(&self, _slf: &ZwpTabletPadRingV2Ref, degrees: Fixed) {
449 self.0(_slf, degrees)
450 }
451 }
452
453 /// Event handler for stop events.
454 pub struct Stop<F>(F);
455 impl<F> ZwpTabletPadRingV2EventHandler for Stop<F>
456 where
457 F: Fn(&ZwpTabletPadRingV2Ref),
458 {
459 #[inline]
460 fn stop(&self, _slf: &ZwpTabletPadRingV2Ref) {
461 self.0(_slf)
462 }
463 }
464
465 /// Event handler for frame events.
466 pub struct Frame<F>(F);
467 impl<F> ZwpTabletPadRingV2EventHandler for Frame<F>
468 where
469 F: Fn(&ZwpTabletPadRingV2Ref, u32),
470 {
471 #[inline]
472 fn frame(&self, _slf: &ZwpTabletPadRingV2Ref, time: u32) {
473 self.0(_slf, time)
474 }
475 }
476
477 impl ZwpTabletPadRingV2 {
478 /// Creates an event handler for source events.
479 ///
480 /// The event handler ignores all other events.
481 #[allow(dead_code)]
482 pub fn on_source<F>(f: F) -> Source<F>
483 where
484 F: Fn(&ZwpTabletPadRingV2Ref, ZwpTabletPadRingV2Source),
485 {
486 Source(f)
487 }
488
489 /// Creates an event handler for angle events.
490 ///
491 /// The event handler ignores all other events.
492 #[allow(dead_code)]
493 pub fn on_angle<F>(f: F) -> Angle<F>
494 where
495 F: Fn(&ZwpTabletPadRingV2Ref, Fixed),
496 {
497 Angle(f)
498 }
499
500 /// Creates an event handler for stop events.
501 ///
502 /// The event handler ignores all other events.
503 #[allow(dead_code)]
504 pub fn on_stop<F>(f: F) -> Stop<F>
505 where
506 F: Fn(&ZwpTabletPadRingV2Ref),
507 {
508 Stop(f)
509 }
510
511 /// Creates an event handler for frame events.
512 ///
513 /// The event handler ignores all other events.
514 #[allow(dead_code)]
515 pub fn on_frame<F>(f: F) -> Frame<F>
516 where
517 F: Fn(&ZwpTabletPadRingV2Ref, u32),
518 {
519 Frame(f)
520 }
521 }
522}