simple_window/common/protocols/tablet_v2/zwp_tablet_pad_group_v2.rs
1//! a set of buttons, rings and strips
2//!
3//! A pad group describes a distinct (sub)set of buttons, rings and strips
4//! present in the tablet. The criteria of this grouping is usually positional,
5//! eg. if a tablet has buttons on the left and right side, 2 groups will be
6//! presented. The physical arrangement of groups is undisclosed and may
7//! change on the fly.
8//!
9//! Pad groups will announce their features during pad initialization. Between
10//! the corresponding wp_tablet_pad.group event and wp_tablet_pad_group.done, the
11//! pad group will announce the buttons, rings and strips contained in it,
12//! plus the number of supported modes.
13//!
14//! Modes are a mechanism to allow multiple groups of actions for every element
15//! in the pad group. The number of groups and available modes in each is
16//! persistent across device plugs. The current mode is user-switchable, it
17//! will be announced through the wp_tablet_pad_group.mode_switch event both
18//! whenever it is switched, and after wp_tablet_pad.enter.
19//!
20//! The current mode logically applies to all elements in the pad group,
21//! although it is at clients' discretion whether to actually perform different
22//! actions, and/or issue the respective .set_feedback requests to notify the
23//! compositor. See the wp_tablet_pad_group.mode_switch event for more details.
24
25use {super::super::all_types::*, ::wl_client::builder::prelude::*};
26
27static INTERFACE: wl_interface = wl_interface {
28 name: c"zwp_tablet_pad_group_v2".as_ptr(),
29 version: 1,
30 method_count: 1,
31 methods: {
32 static MESSAGES: [wl_message; 1] = [wl_message {
33 name: c"destroy".as_ptr(),
34 signature: c"".as_ptr(),
35 types: {
36 static TYPES: [Option<&'static wl_interface>; 0] = [];
37 TYPES.as_ptr().cast()
38 },
39 }];
40 MESSAGES.as_ptr()
41 },
42 event_count: 6,
43 events: {
44 static MESSAGES: [wl_message; 6] = [
45 wl_message {
46 name: c"buttons".as_ptr(),
47 signature: c"a".as_ptr(),
48 types: {
49 static TYPES: [Option<&'static wl_interface>; 1] = [None];
50 TYPES.as_ptr().cast()
51 },
52 },
53 wl_message {
54 name: c"ring".as_ptr(),
55 signature: c"n".as_ptr(),
56 types: {
57 static TYPES: [Option<&'static wl_interface>; 1] =
58 [Some(ZwpTabletPadRingV2::WL_INTERFACE)];
59 TYPES.as_ptr().cast()
60 },
61 },
62 wl_message {
63 name: c"strip".as_ptr(),
64 signature: c"n".as_ptr(),
65 types: {
66 static TYPES: [Option<&'static wl_interface>; 1] =
67 [Some(ZwpTabletPadStripV2::WL_INTERFACE)];
68 TYPES.as_ptr().cast()
69 },
70 },
71 wl_message {
72 name: c"modes".as_ptr(),
73 signature: c"u".as_ptr(),
74 types: {
75 static TYPES: [Option<&'static wl_interface>; 1] = [None];
76 TYPES.as_ptr().cast()
77 },
78 },
79 wl_message {
80 name: c"done".as_ptr(),
81 signature: c"".as_ptr(),
82 types: {
83 static TYPES: [Option<&'static wl_interface>; 0] = [];
84 TYPES.as_ptr().cast()
85 },
86 },
87 wl_message {
88 name: c"mode_switch".as_ptr(),
89 signature: c"uuu".as_ptr(),
90 types: {
91 static TYPES: [Option<&'static wl_interface>; 3] = [None, None, None];
92 TYPES.as_ptr().cast()
93 },
94 },
95 ];
96 MESSAGES.as_ptr()
97 },
98};
99
100/// An owned zwp_tablet_pad_group_v2 proxy.
101///
102/// See the documentation of [the module][self] for the interface description.
103#[derive(Clone, Eq, PartialEq)]
104#[repr(transparent)]
105pub struct ZwpTabletPadGroupV2 {
106 /// This proxy has the interface INTERFACE.
107 proxy: UntypedOwnedProxy,
108}
109
110/// A borrowed zwp_tablet_pad_group_v2 proxy.
111///
112/// See the documentation of [the module][self] for the interface description.
113#[derive(Eq, PartialEq)]
114#[repr(transparent)]
115pub struct ZwpTabletPadGroupV2Ref {
116 /// This proxy has the interface INTERFACE.
117 proxy: UntypedBorrowedProxy,
118}
119
120// SAFETY: ZwpTabletPadGroupV2 is a transparent wrapper around UntypedOwnedProxy
121unsafe impl UntypedOwnedProxyWrapper for ZwpTabletPadGroupV2 {}
122
123// SAFETY: - INTERFACE is a valid wl_interface
124// - The only invariant is that self.proxy has a compatible interface
125unsafe impl OwnedProxy for ZwpTabletPadGroupV2 {
126 const INTERFACE: &'static str = "zwp_tablet_pad_group_v2";
127 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
128 const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
129 private::EventHandler(private::NoOpEventHandler);
130 const MAX_VERSION: u32 = 1;
131
132 type Borrowed = ZwpTabletPadGroupV2Ref;
133 type Api = private::ProxyApi;
134 type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
135}
136
137// SAFETY: ZwpTabletPadGroupV2Ref is a transparent wrapper around UntypedBorrowedProxy
138unsafe impl UntypedBorrowedProxyWrapper for ZwpTabletPadGroupV2Ref {}
139
140// SAFETY: - The only invariant is that self.proxy has a compatible interface
141unsafe impl BorrowedProxy for ZwpTabletPadGroupV2Ref {
142 type Owned = ZwpTabletPadGroupV2;
143}
144
145impl Deref for ZwpTabletPadGroupV2 {
146 type Target = ZwpTabletPadGroupV2Ref;
147
148 fn deref(&self) -> &Self::Target {
149 proxy::low_level::deref(self)
150 }
151}
152
153mod private {
154 pub struct ProxyApi;
155
156 #[allow(dead_code)]
157 pub struct EventHandler<H>(pub(super) H);
158
159 #[allow(dead_code)]
160 pub struct NoOpEventHandler;
161}
162
163impl Debug for ZwpTabletPadGroupV2 {
164 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
165 write!(f, "zwp_tablet_pad_group_v2#{}", self.proxy.id())
166 }
167}
168
169impl Debug for ZwpTabletPadGroupV2Ref {
170 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
171 write!(f, "zwp_tablet_pad_group_v2#{}", self.proxy.id())
172 }
173}
174
175impl PartialEq<ZwpTabletPadGroupV2Ref> for ZwpTabletPadGroupV2 {
176 fn eq(&self, other: &ZwpTabletPadGroupV2Ref) -> bool {
177 self.proxy == other.proxy
178 }
179}
180
181impl PartialEq<ZwpTabletPadGroupV2> for ZwpTabletPadGroupV2Ref {
182 fn eq(&self, other: &ZwpTabletPadGroupV2) -> bool {
183 self.proxy == other.proxy
184 }
185}
186
187#[allow(dead_code)]
188impl ZwpTabletPadGroupV2 {
189 /// Since when the destroy request is available.
190 #[allow(dead_code)]
191 pub const REQ__DESTROY__SINCE: u32 = 1;
192
193 /// destroy the pad object
194 ///
195 /// Destroy the wp_tablet_pad_group object. Objects created from this object
196 /// are unaffected and should be destroyed separately.
197 #[inline]
198 pub fn destroy(&self) {
199 let mut args = [];
200 // SAFETY: - self.proxy has the interface INTERFACE
201 // - 0 < INTERFACE.method_count = 1
202 // - the request signature is ``
203 unsafe {
204 self.proxy.send_destructor(0, &mut args);
205 }
206 }
207}
208
209impl ZwpTabletPadGroupV2 {
210 /// Since when the buttons event is available.
211 #[allow(dead_code)]
212 pub const EVT__BUTTONS__SINCE: u32 = 1;
213
214 /// Since when the ring event is available.
215 #[allow(dead_code)]
216 pub const EVT__RING__SINCE: u32 = 1;
217
218 /// Since when the strip event is available.
219 #[allow(dead_code)]
220 pub const EVT__STRIP__SINCE: u32 = 1;
221
222 /// Since when the modes event is available.
223 #[allow(dead_code)]
224 pub const EVT__MODES__SINCE: u32 = 1;
225
226 /// Since when the done event is available.
227 #[allow(dead_code)]
228 pub const EVT__DONE__SINCE: u32 = 1;
229
230 /// Since when the mode_switch event is available.
231 #[allow(dead_code)]
232 pub const EVT__MODE_SWITCH__SINCE: u32 = 1;
233}
234
235/// An event handler for [ZwpTabletPadGroupV2] proxies.
236#[allow(dead_code)]
237pub trait ZwpTabletPadGroupV2EventHandler {
238 /// buttons announced
239 ///
240 /// Sent on wp_tablet_pad_group initialization to announce the available
241 /// buttons in the group. Button indices start at 0, a button may only be
242 /// in one group at a time.
243 ///
244 /// This event is first sent in the initial burst of events before the
245 /// wp_tablet_pad_group.done event.
246 ///
247 /// Some buttons are reserved by the compositor. These buttons may not be
248 /// assigned to any wp_tablet_pad_group. Compositors may broadcast this
249 /// event in the case of changes to the mapping of these reserved buttons.
250 /// If the compositor happens to reserve all buttons in a group, this event
251 /// will be sent with an empty array.
252 ///
253 /// # Arguments
254 ///
255 /// - `buttons`: buttons in this group
256 #[inline]
257 fn buttons(&self, _slf: &ZwpTabletPadGroupV2Ref, buttons: &[u8]) {
258 let _ = buttons;
259 }
260
261 /// ring announced
262 ///
263 /// Sent on wp_tablet_pad_group initialization to announce available rings.
264 /// One event is sent for each ring available on this pad group.
265 ///
266 /// This event is sent in the initial burst of events before the
267 /// wp_tablet_pad_group.done event.
268 ///
269 /// # Arguments
270 ///
271 /// - `ring`:
272 #[inline]
273 fn ring(&self, _slf: &ZwpTabletPadGroupV2Ref, ring: ZwpTabletPadRingV2) {
274 let _ = ring;
275 }
276
277 /// strip announced
278 ///
279 /// Sent on wp_tablet_pad initialization to announce available strips.
280 /// One event is sent for each strip available on this pad group.
281 ///
282 /// This event is sent in the initial burst of events before the
283 /// wp_tablet_pad_group.done event.
284 ///
285 /// # Arguments
286 ///
287 /// - `strip`:
288 #[inline]
289 fn strip(&self, _slf: &ZwpTabletPadGroupV2Ref, strip: ZwpTabletPadStripV2) {
290 let _ = strip;
291 }
292
293 /// mode-switch ability announced
294 ///
295 /// Sent on wp_tablet_pad_group initialization to announce that the pad
296 /// group may switch between modes. A client may use a mode to store a
297 /// specific configuration for buttons, rings and strips and use the
298 /// wl_tablet_pad_group.mode_switch event to toggle between these
299 /// configurations. Mode indices start at 0.
300 ///
301 /// Switching modes is compositor-dependent. See the
302 /// wp_tablet_pad_group.mode_switch event for more details.
303 ///
304 /// This event is sent in the initial burst of events before the
305 /// wp_tablet_pad_group.done event. This event is only sent when more than
306 /// more than one mode is available.
307 ///
308 /// # Arguments
309 ///
310 /// - `modes`: the number of modes
311 #[inline]
312 fn modes(&self, _slf: &ZwpTabletPadGroupV2Ref, modes: u32) {
313 let _ = modes;
314 }
315
316 /// tablet group description events sequence complete
317 ///
318 /// This event is sent immediately to signal the end of the initial
319 /// burst of descriptive events. A client may consider the static
320 /// description of the tablet to be complete and finalize initialization
321 /// of the tablet group.
322 #[inline]
323 fn done(&self, _slf: &ZwpTabletPadGroupV2Ref) {}
324
325 /// mode switch event
326 ///
327 /// Notification that the mode was switched.
328 ///
329 /// A mode applies to all buttons, rings and strips in a group
330 /// simultaneously, but a client is not required to assign different actions
331 /// for each mode. For example, a client may have mode-specific button
332 /// mappings but map the ring to vertical scrolling in all modes. Mode
333 /// indices start at 0.
334 ///
335 /// Switching modes is compositor-dependent. The compositor may provide
336 /// visual cues to the user about the mode, e.g. by toggling LEDs on
337 /// the tablet device. Mode-switching may be software-controlled or
338 /// controlled by one or more physical buttons. For example, on a Wacom
339 /// Intuos Pro, the button inside the ring may be assigned to switch
340 /// between modes.
341 ///
342 /// The compositor will also send this event after wp_tablet_pad.enter on
343 /// each group in order to notify of the current mode. Groups that only
344 /// feature one mode will use mode=0 when emitting this event.
345 ///
346 /// If a button action in the new mode differs from the action in the
347 /// previous mode, the client should immediately issue a
348 /// wp_tablet_pad.set_feedback request for each changed button.
349 ///
350 /// If a ring or strip action in the new mode differs from the action
351 /// in the previous mode, the client should immediately issue a
352 /// wp_tablet_ring.set_feedback or wp_tablet_strip.set_feedback request
353 /// for each changed ring or strip.
354 ///
355 /// # Arguments
356 ///
357 /// - `time`: the time of the event with millisecond granularity
358 /// - `serial`:
359 /// - `mode`: the new mode of the pad
360 #[inline]
361 fn mode_switch(&self, _slf: &ZwpTabletPadGroupV2Ref, time: u32, serial: u32, mode: u32) {
362 let _ = time;
363 let _ = serial;
364 let _ = mode;
365 }
366}
367
368impl ZwpTabletPadGroupV2EventHandler for private::NoOpEventHandler {}
369
370// SAFETY: - INTERFACE is a valid wl_interface
371unsafe impl<H> EventHandler for private::EventHandler<H>
372where
373 H: ZwpTabletPadGroupV2EventHandler,
374{
375 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
376
377 #[allow(unused_variables)]
378 unsafe fn handle_event(
379 &self,
380 queue: &Queue,
381 data: *mut u8,
382 slf: &UntypedBorrowedProxy,
383 opcode: u32,
384 args: *mut wl_argument,
385 ) {
386 // SAFETY: This function requires that slf has the interface INTERFACE
387 let slf = unsafe { proxy::low_level::from_untyped_borrowed::<ZwpTabletPadGroupV2Ref>(slf) };
388 match opcode {
389 0 => {
390 // SAFETY: INTERFACE requires that there are 1 arguments
391 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
392 // SAFETY: - INTERFACE requires that args[0] contains an array
393 let arg0 = unsafe {
394 let a = &*args[0].a;
395 std::slice::from_raw_parts(a.data.cast(), a.size)
396 };
397 self.0.buttons(slf, arg0);
398 }
399 1 => {
400 // SAFETY: INTERFACE requires that there are 1 arguments
401 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
402 // SAFETY: - INTERFACE requires that args[0] contains an object
403 // - ownership is transferred to this function
404 // - INTERFACE requires that the object has the interface ZwpTabletPadRingV2::WL_INTERFACE
405 let arg0 = unsafe {
406 UntypedOwnedProxy::from_plain_wl_proxy(
407 queue,
408 NonNull::new_unchecked(args[0].o.cast()),
409 ZwpTabletPadRingV2::WL_INTERFACE,
410 )
411 };
412 // SAFETY: - INTERFACE requires that the object has the interface ZwpTabletPadRingV2::WL_INTERFACE
413 let arg0 =
414 unsafe { proxy::low_level::from_untyped_owned::<ZwpTabletPadRingV2>(arg0) };
415 self.0.ring(slf, arg0);
416 }
417 2 => {
418 // SAFETY: INTERFACE requires that there are 1 arguments
419 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
420 // SAFETY: - INTERFACE requires that args[0] contains an object
421 // - ownership is transferred to this function
422 // - INTERFACE requires that the object has the interface ZwpTabletPadStripV2::WL_INTERFACE
423 let arg0 = unsafe {
424 UntypedOwnedProxy::from_plain_wl_proxy(
425 queue,
426 NonNull::new_unchecked(args[0].o.cast()),
427 ZwpTabletPadStripV2::WL_INTERFACE,
428 )
429 };
430 // SAFETY: - INTERFACE requires that the object has the interface ZwpTabletPadStripV2::WL_INTERFACE
431 let arg0 =
432 unsafe { proxy::low_level::from_untyped_owned::<ZwpTabletPadStripV2>(arg0) };
433 self.0.strip(slf, arg0);
434 }
435 3 => {
436 // SAFETY: INTERFACE requires that there are 1 arguments
437 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
438 // SAFETY: - INTERFACE requires that args[0] contains a uint
439 let arg0 = unsafe { args[0].u };
440 self.0.modes(slf, arg0);
441 }
442 4 => {
443 self.0.done(slf);
444 }
445 5 => {
446 // SAFETY: INTERFACE requires that there are 3 arguments
447 let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
448 // SAFETY: - INTERFACE requires that args[0] contains a uint
449 let arg0 = unsafe { args[0].u };
450 // SAFETY: - INTERFACE requires that args[1] contains a uint
451 let arg1 = unsafe { args[1].u };
452 // SAFETY: - INTERFACE requires that args[2] contains a uint
453 let arg2 = unsafe { args[2].u };
454 self.0.mode_switch(slf, arg0, arg1, arg2);
455 }
456 _ => {
457 invalid_opcode("zwp_tablet_pad_group_v2", opcode);
458 }
459 }
460 }
461}
462
463impl<H> CreateEventHandler<H> for private::ProxyApi
464where
465 H: ZwpTabletPadGroupV2EventHandler,
466{
467 type EventHandler = private::EventHandler<H>;
468
469 #[inline]
470 fn create_event_handler(handler: H) -> Self::EventHandler {
471 private::EventHandler(handler)
472 }
473}
474
475/// Functional event handlers.
476pub mod event_handlers {
477 use super::*;
478
479 /// Event handler for buttons events.
480 pub struct Buttons<F>(F);
481 impl<F> ZwpTabletPadGroupV2EventHandler for Buttons<F>
482 where
483 F: Fn(&ZwpTabletPadGroupV2Ref, &[u8]),
484 {
485 #[inline]
486 fn buttons(&self, _slf: &ZwpTabletPadGroupV2Ref, buttons: &[u8]) {
487 self.0(_slf, buttons)
488 }
489 }
490
491 /// Event handler for ring events.
492 pub struct Ring<F>(F);
493 impl<F> ZwpTabletPadGroupV2EventHandler for Ring<F>
494 where
495 F: Fn(&ZwpTabletPadGroupV2Ref, ZwpTabletPadRingV2),
496 {
497 #[inline]
498 fn ring(&self, _slf: &ZwpTabletPadGroupV2Ref, ring: ZwpTabletPadRingV2) {
499 self.0(_slf, ring)
500 }
501 }
502
503 /// Event handler for strip events.
504 pub struct Strip<F>(F);
505 impl<F> ZwpTabletPadGroupV2EventHandler for Strip<F>
506 where
507 F: Fn(&ZwpTabletPadGroupV2Ref, ZwpTabletPadStripV2),
508 {
509 #[inline]
510 fn strip(&self, _slf: &ZwpTabletPadGroupV2Ref, strip: ZwpTabletPadStripV2) {
511 self.0(_slf, strip)
512 }
513 }
514
515 /// Event handler for modes events.
516 pub struct Modes<F>(F);
517 impl<F> ZwpTabletPadGroupV2EventHandler for Modes<F>
518 where
519 F: Fn(&ZwpTabletPadGroupV2Ref, u32),
520 {
521 #[inline]
522 fn modes(&self, _slf: &ZwpTabletPadGroupV2Ref, modes: u32) {
523 self.0(_slf, modes)
524 }
525 }
526
527 /// Event handler for done events.
528 pub struct Done<F>(F);
529 impl<F> ZwpTabletPadGroupV2EventHandler for Done<F>
530 where
531 F: Fn(&ZwpTabletPadGroupV2Ref),
532 {
533 #[inline]
534 fn done(&self, _slf: &ZwpTabletPadGroupV2Ref) {
535 self.0(_slf)
536 }
537 }
538
539 /// Event handler for mode_switch events.
540 pub struct ModeSwitch<F>(F);
541 impl<F> ZwpTabletPadGroupV2EventHandler for ModeSwitch<F>
542 where
543 F: Fn(&ZwpTabletPadGroupV2Ref, u32, u32, u32),
544 {
545 #[inline]
546 fn mode_switch(&self, _slf: &ZwpTabletPadGroupV2Ref, time: u32, serial: u32, mode: u32) {
547 self.0(_slf, time, serial, mode)
548 }
549 }
550
551 impl ZwpTabletPadGroupV2 {
552 /// Creates an event handler for buttons events.
553 ///
554 /// The event handler ignores all other events.
555 #[allow(dead_code)]
556 pub fn on_buttons<F>(f: F) -> Buttons<F>
557 where
558 F: Fn(&ZwpTabletPadGroupV2Ref, &[u8]),
559 {
560 Buttons(f)
561 }
562
563 /// Creates an event handler for ring events.
564 ///
565 /// The event handler ignores all other events.
566 #[allow(dead_code)]
567 pub fn on_ring<F>(f: F) -> Ring<F>
568 where
569 F: Fn(&ZwpTabletPadGroupV2Ref, ZwpTabletPadRingV2),
570 {
571 Ring(f)
572 }
573
574 /// Creates an event handler for strip events.
575 ///
576 /// The event handler ignores all other events.
577 #[allow(dead_code)]
578 pub fn on_strip<F>(f: F) -> Strip<F>
579 where
580 F: Fn(&ZwpTabletPadGroupV2Ref, ZwpTabletPadStripV2),
581 {
582 Strip(f)
583 }
584
585 /// Creates an event handler for modes events.
586 ///
587 /// The event handler ignores all other events.
588 #[allow(dead_code)]
589 pub fn on_modes<F>(f: F) -> Modes<F>
590 where
591 F: Fn(&ZwpTabletPadGroupV2Ref, u32),
592 {
593 Modes(f)
594 }
595
596 /// Creates an event handler for done events.
597 ///
598 /// The event handler ignores all other events.
599 #[allow(dead_code)]
600 pub fn on_done<F>(f: F) -> Done<F>
601 where
602 F: Fn(&ZwpTabletPadGroupV2Ref),
603 {
604 Done(f)
605 }
606
607 /// Creates an event handler for mode_switch events.
608 ///
609 /// The event handler ignores all other events.
610 #[allow(dead_code)]
611 pub fn on_mode_switch<F>(f: F) -> ModeSwitch<F>
612 where
613 F: Fn(&ZwpTabletPadGroupV2Ref, u32, u32, u32),
614 {
615 ModeSwitch(f)
616 }
617 }
618}