simple_window/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 data: *mut u8,
344 slf: &UntypedBorrowedProxy,
345 opcode: u32,
346 args: *mut wl_argument,
347 ) {
348 // SAFETY: This function requires that slf has the interface INTERFACE
349 let slf = unsafe { proxy::low_level::from_untyped_borrowed::<ZwpTabletPadRingV2Ref>(slf) };
350 match opcode {
351 0 => {
352 // SAFETY: INTERFACE requires that there are 1 arguments
353 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
354 // SAFETY: - INTERFACE requires that args[0] contains a uint
355 let arg0 = unsafe { ZwpTabletPadRingV2Source(args[0].u) };
356 self.0.source(slf, arg0);
357 }
358 1 => {
359 // SAFETY: INTERFACE requires that there are 1 arguments
360 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
361 // SAFETY: - INTERFACE requires that args[0] contains a fixed
362 let arg0 = unsafe { Fixed::from_wire(args[0].f) };
363 self.0.angle(slf, arg0);
364 }
365 2 => {
366 self.0.stop(slf);
367 }
368 3 => {
369 // SAFETY: INTERFACE requires that there are 1 arguments
370 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
371 // SAFETY: - INTERFACE requires that args[0] contains a uint
372 let arg0 = unsafe { args[0].u };
373 self.0.frame(slf, arg0);
374 }
375 _ => {
376 invalid_opcode("zwp_tablet_pad_ring_v2", opcode);
377 }
378 }
379 }
380}
381
382impl<H> CreateEventHandler<H> for private::ProxyApi
383where
384 H: ZwpTabletPadRingV2EventHandler,
385{
386 type EventHandler = private::EventHandler<H>;
387
388 #[inline]
389 fn create_event_handler(handler: H) -> Self::EventHandler {
390 private::EventHandler(handler)
391 }
392}
393
394impl ZwpTabletPadRingV2 {
395 /// Since when the source.finger enum variant is available.
396 #[allow(dead_code)]
397 pub const ENM__SOURCE_FINGER__SINCE: u32 = 1;
398}
399
400/// ring axis source
401///
402/// Describes the source types for ring events. This indicates to the
403/// client how a ring event was physically generated; a client may
404/// adjust the user interface accordingly. For example, events
405/// from a "finger" source may trigger kinetic scrolling.
406#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
407#[allow(dead_code)]
408pub struct ZwpTabletPadRingV2Source(pub u32);
409
410impl ZwpTabletPadRingV2Source {
411 /// finger
412 #[allow(dead_code)]
413 pub const FINGER: Self = Self(1);
414}
415
416impl Debug for ZwpTabletPadRingV2Source {
417 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
418 let name = match *self {
419 Self::FINGER => "FINGER",
420 _ => return Debug::fmt(&self.0, f),
421 };
422 f.write_str(name)
423 }
424}
425
426/// Functional event handlers.
427pub mod event_handlers {
428 use super::*;
429
430 /// Event handler for source events.
431 pub struct Source<F>(F);
432 impl<F> ZwpTabletPadRingV2EventHandler for Source<F>
433 where
434 F: Fn(&ZwpTabletPadRingV2Ref, ZwpTabletPadRingV2Source),
435 {
436 #[inline]
437 fn source(&self, _slf: &ZwpTabletPadRingV2Ref, source: ZwpTabletPadRingV2Source) {
438 self.0(_slf, source)
439 }
440 }
441
442 /// Event handler for angle events.
443 pub struct Angle<F>(F);
444 impl<F> ZwpTabletPadRingV2EventHandler for Angle<F>
445 where
446 F: Fn(&ZwpTabletPadRingV2Ref, Fixed),
447 {
448 #[inline]
449 fn angle(&self, _slf: &ZwpTabletPadRingV2Ref, degrees: Fixed) {
450 self.0(_slf, degrees)
451 }
452 }
453
454 /// Event handler for stop events.
455 pub struct Stop<F>(F);
456 impl<F> ZwpTabletPadRingV2EventHandler for Stop<F>
457 where
458 F: Fn(&ZwpTabletPadRingV2Ref),
459 {
460 #[inline]
461 fn stop(&self, _slf: &ZwpTabletPadRingV2Ref) {
462 self.0(_slf)
463 }
464 }
465
466 /// Event handler for frame events.
467 pub struct Frame<F>(F);
468 impl<F> ZwpTabletPadRingV2EventHandler for Frame<F>
469 where
470 F: Fn(&ZwpTabletPadRingV2Ref, u32),
471 {
472 #[inline]
473 fn frame(&self, _slf: &ZwpTabletPadRingV2Ref, time: u32) {
474 self.0(_slf, time)
475 }
476 }
477
478 impl ZwpTabletPadRingV2 {
479 /// Creates an event handler for source events.
480 ///
481 /// The event handler ignores all other events.
482 #[allow(dead_code)]
483 pub fn on_source<F>(f: F) -> Source<F>
484 where
485 F: Fn(&ZwpTabletPadRingV2Ref, ZwpTabletPadRingV2Source),
486 {
487 Source(f)
488 }
489
490 /// Creates an event handler for angle events.
491 ///
492 /// The event handler ignores all other events.
493 #[allow(dead_code)]
494 pub fn on_angle<F>(f: F) -> Angle<F>
495 where
496 F: Fn(&ZwpTabletPadRingV2Ref, Fixed),
497 {
498 Angle(f)
499 }
500
501 /// Creates an event handler for stop events.
502 ///
503 /// The event handler ignores all other events.
504 #[allow(dead_code)]
505 pub fn on_stop<F>(f: F) -> Stop<F>
506 where
507 F: Fn(&ZwpTabletPadRingV2Ref),
508 {
509 Stop(f)
510 }
511
512 /// Creates an event handler for frame events.
513 ///
514 /// The event handler ignores all other events.
515 #[allow(dead_code)]
516 pub fn on_frame<F>(f: F) -> Frame<F>
517 where
518 F: Fn(&ZwpTabletPadRingV2Ref, u32),
519 {
520 Frame(f)
521 }
522 }
523}