simple_window/common/protocols/tablet_v2/zwp_tablet_pad_strip_v2.rs
1//! pad strip
2//!
3//! A linear interaction area, such as the strips found in Wacom Cintiq
4//! models.
5//!
6//! Events on a strip are logically grouped by the wl_tablet_pad_strip.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_strip_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"position".as_ptr(),
49 signature: c"u".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_strip_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 ZwpTabletPadStripV2 {
82 /// This proxy has the interface INTERFACE.
83 proxy: UntypedOwnedProxy,
84}
85
86/// A borrowed zwp_tablet_pad_strip_v2 proxy.
87///
88/// See the documentation of [the module][self] for the interface description.
89#[derive(Eq, PartialEq)]
90#[repr(transparent)]
91pub struct ZwpTabletPadStripV2Ref {
92 /// This proxy has the interface INTERFACE.
93 proxy: UntypedBorrowedProxy,
94}
95
96// SAFETY: ZwpTabletPadStripV2 is a transparent wrapper around UntypedOwnedProxy
97unsafe impl UntypedOwnedProxyWrapper for ZwpTabletPadStripV2 {}
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 ZwpTabletPadStripV2 {
102 const INTERFACE: &'static str = "zwp_tablet_pad_strip_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 = ZwpTabletPadStripV2Ref;
109 type Api = private::ProxyApi;
110 type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
111}
112
113// SAFETY: ZwpTabletPadStripV2Ref is a transparent wrapper around UntypedBorrowedProxy
114unsafe impl UntypedBorrowedProxyWrapper for ZwpTabletPadStripV2Ref {}
115
116// SAFETY: - The only invariant is that self.proxy has a compatible interface
117unsafe impl BorrowedProxy for ZwpTabletPadStripV2Ref {
118 type Owned = ZwpTabletPadStripV2;
119}
120
121impl Deref for ZwpTabletPadStripV2 {
122 type Target = ZwpTabletPadStripV2Ref;
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 ZwpTabletPadStripV2 {
140 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
141 write!(f, "zwp_tablet_pad_strip_v2#{}", self.proxy.id())
142 }
143}
144
145impl Debug for ZwpTabletPadStripV2Ref {
146 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
147 write!(f, "zwp_tablet_pad_strip_v2#{}", self.proxy.id())
148 }
149}
150
151impl PartialEq<ZwpTabletPadStripV2Ref> for ZwpTabletPadStripV2 {
152 fn eq(&self, other: &ZwpTabletPadStripV2Ref) -> bool {
153 self.proxy == other.proxy
154 }
155}
156
157impl PartialEq<ZwpTabletPadStripV2> for ZwpTabletPadStripV2Ref {
158 fn eq(&self, other: &ZwpTabletPadStripV2) -> bool {
159 self.proxy == other.proxy
160 }
161}
162
163#[allow(dead_code)]
164impl ZwpTabletPadStripV2 {
165 /// Since when the destroy request is available.
166 #[allow(dead_code)]
167 pub const REQ__DESTROY__SINCE: u32 = 1;
168
169 /// destroy the strip object
170 ///
171 /// This destroys the client's resource for this strip 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 ZwpTabletPadStripV2Ref {
186 /// set compositor feedback
187 ///
188 /// Requests the compositor to use the provided feedback string
189 /// associated with this strip. 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 strip 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 strip, and 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 /// strip. Requests providing other serials than the most recent one will be
206 /// ignored.
207 ///
208 /// # Arguments
209 ///
210 /// - `description`: strip 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 ZwpTabletPadStripV2 {
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 position event is available.
237 #[allow(dead_code)]
238 pub const EVT__POSITION__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 [ZwpTabletPadStripV2] proxies.
250#[allow(dead_code)]
251pub trait ZwpTabletPadStripV2EventHandler {
252 /// strip event source
253 ///
254 /// Source information for strip events.
255 ///
256 /// This event does not occur on its own. It is sent before a
257 /// wp_tablet_pad_strip.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_strip.source.finger, a wp_tablet_pad_strip.stop event
262 /// will be sent when the user lifts their 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: &ZwpTabletPadStripV2Ref, source: ZwpTabletPadStripV2Source) {
272 let _ = source;
273 }
274
275 /// position changed
276 ///
277 /// Sent whenever the position on a strip changes.
278 ///
279 /// The position is normalized to a range of [0, 65535], the 0-value
280 /// represents the top-most and/or left-most position of the strip in
281 /// the pad's current rotation.
282 ///
283 /// # Arguments
284 ///
285 /// - `position`: the current position
286 #[inline]
287 fn position(&self, _slf: &ZwpTabletPadStripV2Ref, position: u32) {
288 let _ = position;
289 }
290
291 /// interaction stopped
292 ///
293 /// Stop notification for strip events.
294 ///
295 /// For some wp_tablet_pad_strip.source types, a wp_tablet_pad_strip.stop
296 /// event is sent to notify a client that the interaction with the strip
297 /// has terminated. This enables the client to implement kinetic
298 /// scrolling. See the wp_tablet_pad_strip.source documentation for
299 /// information on when this event may be generated.
300 ///
301 /// Any wp_tablet_pad_strip.position events with the same source after this
302 /// event should be considered as the start of a new interaction.
303 #[inline]
304 fn stop(&self, _slf: &ZwpTabletPadStripV2Ref) {}
305
306 /// end of a strip event sequence
307 ///
308 /// Indicates the end of a set of events that represent one logical
309 /// hardware strip event. A client is expected to accumulate the data
310 /// in all events within the frame before proceeding.
311 ///
312 /// All wp_tablet_pad_strip events before a wp_tablet_pad_strip.frame event belong
313 /// logically together. For example, on termination of a finger interaction
314 /// on a strip the compositor will send a wp_tablet_pad_strip.source event,
315 /// a wp_tablet_pad_strip.stop event and a wp_tablet_pad_strip.frame
316 /// event.
317 ///
318 /// A wp_tablet_pad_strip.frame event is sent for every logical event
319 /// group, even if the group only contains a single wp_tablet_pad_strip
320 /// event. Specifically, a client may get a sequence: position, frame,
321 /// position, frame, etc.
322 ///
323 /// # Arguments
324 ///
325 /// - `time`: timestamp with millisecond granularity
326 #[inline]
327 fn frame(&self, _slf: &ZwpTabletPadStripV2Ref, time: u32) {
328 let _ = time;
329 }
330}
331
332impl ZwpTabletPadStripV2EventHandler for private::NoOpEventHandler {}
333
334// SAFETY: - INTERFACE is a valid wl_interface
335unsafe impl<H> EventHandler for private::EventHandler<H>
336where
337 H: ZwpTabletPadStripV2EventHandler,
338{
339 const WL_INTERFACE: &'static wl_interface = &INTERFACE;
340
341 #[allow(unused_variables)]
342 unsafe fn handle_event(
343 &self,
344 queue: &Queue,
345 data: *mut u8,
346 slf: &UntypedBorrowedProxy,
347 opcode: u32,
348 args: *mut wl_argument,
349 ) {
350 // SAFETY: This function requires that slf has the interface INTERFACE
351 let slf = unsafe { proxy::low_level::from_untyped_borrowed::<ZwpTabletPadStripV2Ref>(slf) };
352 match opcode {
353 0 => {
354 // SAFETY: INTERFACE requires that there are 1 arguments
355 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
356 // SAFETY: - INTERFACE requires that args[0] contains a uint
357 let arg0 = unsafe { ZwpTabletPadStripV2Source(args[0].u) };
358 self.0.source(slf, arg0);
359 }
360 1 => {
361 // SAFETY: INTERFACE requires that there are 1 arguments
362 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
363 // SAFETY: - INTERFACE requires that args[0] contains a uint
364 let arg0 = unsafe { args[0].u };
365 self.0.position(slf, arg0);
366 }
367 2 => {
368 self.0.stop(slf);
369 }
370 3 => {
371 // SAFETY: INTERFACE requires that there are 1 arguments
372 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
373 // SAFETY: - INTERFACE requires that args[0] contains a uint
374 let arg0 = unsafe { args[0].u };
375 self.0.frame(slf, arg0);
376 }
377 _ => {
378 invalid_opcode("zwp_tablet_pad_strip_v2", opcode);
379 }
380 }
381 }
382}
383
384impl<H> CreateEventHandler<H> for private::ProxyApi
385where
386 H: ZwpTabletPadStripV2EventHandler,
387{
388 type EventHandler = private::EventHandler<H>;
389
390 #[inline]
391 fn create_event_handler(handler: H) -> Self::EventHandler {
392 private::EventHandler(handler)
393 }
394}
395
396impl ZwpTabletPadStripV2 {
397 /// Since when the source.finger enum variant is available.
398 #[allow(dead_code)]
399 pub const ENM__SOURCE_FINGER__SINCE: u32 = 1;
400}
401
402/// strip axis source
403///
404/// Describes the source types for strip events. This indicates to the
405/// client how a strip event was physically generated; a client may
406/// adjust the user interface accordingly. For example, events
407/// from a "finger" source may trigger kinetic scrolling.
408#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
409#[allow(dead_code)]
410pub struct ZwpTabletPadStripV2Source(pub u32);
411
412impl ZwpTabletPadStripV2Source {
413 /// finger
414 #[allow(dead_code)]
415 pub const FINGER: Self = Self(1);
416}
417
418impl Debug for ZwpTabletPadStripV2Source {
419 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
420 let name = match *self {
421 Self::FINGER => "FINGER",
422 _ => return Debug::fmt(&self.0, f),
423 };
424 f.write_str(name)
425 }
426}
427
428/// Functional event handlers.
429pub mod event_handlers {
430 use super::*;
431
432 /// Event handler for source events.
433 pub struct Source<F>(F);
434 impl<F> ZwpTabletPadStripV2EventHandler for Source<F>
435 where
436 F: Fn(&ZwpTabletPadStripV2Ref, ZwpTabletPadStripV2Source),
437 {
438 #[inline]
439 fn source(&self, _slf: &ZwpTabletPadStripV2Ref, source: ZwpTabletPadStripV2Source) {
440 self.0(_slf, source)
441 }
442 }
443
444 /// Event handler for position events.
445 pub struct Position<F>(F);
446 impl<F> ZwpTabletPadStripV2EventHandler for Position<F>
447 where
448 F: Fn(&ZwpTabletPadStripV2Ref, u32),
449 {
450 #[inline]
451 fn position(&self, _slf: &ZwpTabletPadStripV2Ref, position: u32) {
452 self.0(_slf, position)
453 }
454 }
455
456 /// Event handler for stop events.
457 pub struct Stop<F>(F);
458 impl<F> ZwpTabletPadStripV2EventHandler for Stop<F>
459 where
460 F: Fn(&ZwpTabletPadStripV2Ref),
461 {
462 #[inline]
463 fn stop(&self, _slf: &ZwpTabletPadStripV2Ref) {
464 self.0(_slf)
465 }
466 }
467
468 /// Event handler for frame events.
469 pub struct Frame<F>(F);
470 impl<F> ZwpTabletPadStripV2EventHandler for Frame<F>
471 where
472 F: Fn(&ZwpTabletPadStripV2Ref, u32),
473 {
474 #[inline]
475 fn frame(&self, _slf: &ZwpTabletPadStripV2Ref, time: u32) {
476 self.0(_slf, time)
477 }
478 }
479
480 impl ZwpTabletPadStripV2 {
481 /// Creates an event handler for source events.
482 ///
483 /// The event handler ignores all other events.
484 #[allow(dead_code)]
485 pub fn on_source<F>(f: F) -> Source<F>
486 where
487 F: Fn(&ZwpTabletPadStripV2Ref, ZwpTabletPadStripV2Source),
488 {
489 Source(f)
490 }
491
492 /// Creates an event handler for position events.
493 ///
494 /// The event handler ignores all other events.
495 #[allow(dead_code)]
496 pub fn on_position<F>(f: F) -> Position<F>
497 where
498 F: Fn(&ZwpTabletPadStripV2Ref, u32),
499 {
500 Position(f)
501 }
502
503 /// Creates an event handler for stop events.
504 ///
505 /// The event handler ignores all other events.
506 #[allow(dead_code)]
507 pub fn on_stop<F>(f: F) -> Stop<F>
508 where
509 F: Fn(&ZwpTabletPadStripV2Ref),
510 {
511 Stop(f)
512 }
513
514 /// Creates an event handler for frame events.
515 ///
516 /// The event handler ignores all other events.
517 #[allow(dead_code)]
518 pub fn on_frame<F>(f: F) -> Frame<F>
519 where
520 F: Fn(&ZwpTabletPadStripV2Ref, u32),
521 {
522 Frame(f)
523 }
524 }
525}