sdl3_sys/generated/
pen.rs

1//! SDL pen event handling.
2//!
3//! SDL provides an API for pressure-sensitive pen (stylus and/or eraser)
4//! handling, e.g., for input and drawing tablets or suitably equipped mobile /
5//! tablet devices.
6//!
7//! To get started with pens, simply handle pen events:
8//!
9//! - [`SDL_EVENT_PEN_PROXIMITY_IN`], [`SDL_EVENT_PEN_PROXIMITY_OUT`]
10//!   ([`SDL_PenProximityEvent`])
11//! - [`SDL_EVENT_PEN_DOWN`], [`SDL_EVENT_PEN_UP`] ([`SDL_PenTouchEvent`])
12//! - [`SDL_EVENT_PEN_MOTION`] ([`SDL_PenMotionEvent`])
13//! - [`SDL_EVENT_PEN_BUTTON_DOWN`], [`SDL_EVENT_PEN_BUTTON_UP`] ([`SDL_PenButtonEvent`])
14//! - [`SDL_EVENT_PEN_AXIS`] ([`SDL_PenAxisEvent`])
15//!
16//! Pens may provide more than simple touch input; they might have other axes,
17//! such as pressure, tilt, rotation, etc.
18//!
19//! When a pen starts providing input, SDL will assign it a unique [`SDL_PenID`],
20//! which will remain for the life of the process, as long as the pen stays
21//! connected. A pen leaving proximity (being taken far enough away from the
22//! digitizer tablet that it no longer reponds) and then coming back should
23//! fire proximity events, but the [`SDL_PenID`] should remain consistent.
24//! Unplugging the digitizer and reconnecting may cause future input to have a
25//! new [`SDL_PenID`], as SDL may not know that this is the same hardware.
26//!
27//! Please note that various platforms vary wildly in how (and how well) they
28//! support pen input. If your pen supports some piece of functionality but SDL
29//! doesn't seem to, it might actually be the operating system's fault. For
30//! example, some platforms can manage multiple devices at the same time, but
31//! others will make any connected pens look like a single logical device, much
32//! how all USB mice connected to a computer will move the same system cursor.
33//! cursor. Other platforms might not support pen buttons, or the distance
34//! axis, etc. Very few platforms can even report _what_ functionality the pen
35//! supports in the first place, so best practices is to either build UI to let
36//! the user configure their pens, or be prepared to handle new functionality
37//! for a pen the first time an event is reported.
38
39use super::stdinc::*;
40
41use super::mouse::*;
42
43use super::touch::*;
44
45/// SDL pen instance IDs.
46///
47/// Zero is used to signify an invalid/null device.
48///
49/// These show up in pen events when SDL sees input from them. They remain
50/// consistent as long as SDL can recognize a tool to be the same pen; but if a
51/// pen's digitizer table is physically detached from the computer, it might
52/// get a new ID when reconnected, as SDL won't know it's the same device.
53///
54/// These IDs are only stable within a single run of a program; the next time a
55/// program is run, the pen's ID will likely be different, even if the hardware
56/// hasn't been disconnected, etc.
57///
58/// ## Availability
59/// This datatype is available since SDL 3.2.0.
60#[repr(transparent)]
61#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
62#[cfg_attr(feature = "debug-impls", derive(Debug))]
63pub struct SDL_PenID(pub Uint32);
64
65impl ::core::cmp::PartialEq<Uint32> for SDL_PenID {
66    #[inline(always)]
67    fn eq(&self, other: &Uint32) -> bool {
68        &self.0 == other
69    }
70}
71
72impl ::core::cmp::PartialEq<SDL_PenID> for Uint32 {
73    #[inline(always)]
74    fn eq(&self, other: &SDL_PenID) -> bool {
75        self == &other.0
76    }
77}
78
79impl From<SDL_PenID> for Uint32 {
80    #[inline(always)]
81    fn from(value: SDL_PenID) -> Self {
82        value.0
83    }
84}
85
86#[cfg(feature = "metadata")]
87impl sdl3_sys::metadata::GroupMetadata for SDL_PenID {
88    const GROUP_METADATA: &'static sdl3_sys::metadata::Group =
89        &crate::metadata::pen::METADATA_SDL_PenID;
90}
91
92/// The [`SDL_MouseID`] for mouse events simulated with pen input.
93///
94/// ## Availability
95/// This macro is available since SDL 3.2.0.
96pub const SDL_PEN_MOUSEID: SDL_MouseID = SDL_MouseID((-2_i32 as Uint32));
97
98/// The [`SDL_TouchID`] for touch events simulated with pen input.
99///
100/// ## Availability
101/// This macro is available since SDL 3.2.0.
102pub const SDL_PEN_TOUCHID: SDL_TouchID = SDL_TouchID((-2_i32 as Uint64));
103
104/// Pen input flags, as reported by various pen events' `pen_state` field.
105///
106/// ## Availability
107/// This datatype is available since SDL 3.2.0.
108///
109/// ## Known values (`sdl3-sys`)
110/// | Associated constant | Global constant | Description |
111/// | ------------------- | --------------- | ----------- |
112/// | [`DOWN`](SDL_PenInputFlags::DOWN) | [`SDL_PEN_INPUT_DOWN`] | pen is pressed down |
113/// | [`BUTTON_1`](SDL_PenInputFlags::BUTTON_1) | [`SDL_PEN_INPUT_BUTTON_1`] | button 1 is pressed |
114/// | [`BUTTON_2`](SDL_PenInputFlags::BUTTON_2) | [`SDL_PEN_INPUT_BUTTON_2`] | button 2 is pressed |
115/// | [`BUTTON_3`](SDL_PenInputFlags::BUTTON_3) | [`SDL_PEN_INPUT_BUTTON_3`] | button 3 is pressed |
116/// | [`BUTTON_4`](SDL_PenInputFlags::BUTTON_4) | [`SDL_PEN_INPUT_BUTTON_4`] | button 4 is pressed |
117/// | [`BUTTON_5`](SDL_PenInputFlags::BUTTON_5) | [`SDL_PEN_INPUT_BUTTON_5`] | button 5 is pressed |
118/// | [`ERASER_TIP`](SDL_PenInputFlags::ERASER_TIP) | [`SDL_PEN_INPUT_ERASER_TIP`] | eraser tip is used |
119/// | [`IN_PROXIMITY`](SDL_PenInputFlags::IN_PROXIMITY) | [`SDL_PEN_INPUT_IN_PROXIMITY`] | pen is in proximity (since SDL 3.4.0) |
120#[repr(transparent)]
121#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)]
122pub struct SDL_PenInputFlags(pub Uint32);
123
124impl ::core::cmp::PartialEq<Uint32> for SDL_PenInputFlags {
125    #[inline(always)]
126    fn eq(&self, other: &Uint32) -> bool {
127        &self.0 == other
128    }
129}
130
131impl ::core::cmp::PartialEq<SDL_PenInputFlags> for Uint32 {
132    #[inline(always)]
133    fn eq(&self, other: &SDL_PenInputFlags) -> bool {
134        self == &other.0
135    }
136}
137
138impl From<SDL_PenInputFlags> for Uint32 {
139    #[inline(always)]
140    fn from(value: SDL_PenInputFlags) -> Self {
141        value.0
142    }
143}
144
145#[cfg(feature = "debug-impls")]
146impl ::core::fmt::Debug for SDL_PenInputFlags {
147    fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
148        let mut first = true;
149        let all_bits = 0;
150        write!(f, "SDL_PenInputFlags(")?;
151        let all_bits = all_bits | Self::DOWN.0;
152        if (Self::DOWN != 0 || self.0 == 0) && *self & Self::DOWN == Self::DOWN {
153            if !first {
154                write!(f, " | ")?;
155            }
156            first = false;
157            write!(f, "DOWN")?;
158        }
159        let all_bits = all_bits | Self::BUTTON_1.0;
160        if (Self::BUTTON_1 != 0 || self.0 == 0) && *self & Self::BUTTON_1 == Self::BUTTON_1 {
161            if !first {
162                write!(f, " | ")?;
163            }
164            first = false;
165            write!(f, "BUTTON_1")?;
166        }
167        let all_bits = all_bits | Self::BUTTON_2.0;
168        if (Self::BUTTON_2 != 0 || self.0 == 0) && *self & Self::BUTTON_2 == Self::BUTTON_2 {
169            if !first {
170                write!(f, " | ")?;
171            }
172            first = false;
173            write!(f, "BUTTON_2")?;
174        }
175        let all_bits = all_bits | Self::BUTTON_3.0;
176        if (Self::BUTTON_3 != 0 || self.0 == 0) && *self & Self::BUTTON_3 == Self::BUTTON_3 {
177            if !first {
178                write!(f, " | ")?;
179            }
180            first = false;
181            write!(f, "BUTTON_3")?;
182        }
183        let all_bits = all_bits | Self::BUTTON_4.0;
184        if (Self::BUTTON_4 != 0 || self.0 == 0) && *self & Self::BUTTON_4 == Self::BUTTON_4 {
185            if !first {
186                write!(f, " | ")?;
187            }
188            first = false;
189            write!(f, "BUTTON_4")?;
190        }
191        let all_bits = all_bits | Self::BUTTON_5.0;
192        if (Self::BUTTON_5 != 0 || self.0 == 0) && *self & Self::BUTTON_5 == Self::BUTTON_5 {
193            if !first {
194                write!(f, " | ")?;
195            }
196            first = false;
197            write!(f, "BUTTON_5")?;
198        }
199        let all_bits = all_bits | Self::ERASER_TIP.0;
200        if (Self::ERASER_TIP != 0 || self.0 == 0) && *self & Self::ERASER_TIP == Self::ERASER_TIP {
201            if !first {
202                write!(f, " | ")?;
203            }
204            first = false;
205            write!(f, "ERASER_TIP")?;
206        }
207        let all_bits = all_bits | Self::IN_PROXIMITY.0;
208        if (Self::IN_PROXIMITY != 0 || self.0 == 0)
209            && *self & Self::IN_PROXIMITY == Self::IN_PROXIMITY
210        {
211            if !first {
212                write!(f, " | ")?;
213            }
214            first = false;
215            write!(f, "IN_PROXIMITY")?;
216        }
217
218        if self.0 & !all_bits != 0 {
219            if !first {
220                write!(f, " | ")?;
221            }
222            write!(f, "{:#x}", self.0)?;
223        } else if first {
224            write!(f, "0")?;
225        }
226        write!(f, ")")
227    }
228}
229
230impl ::core::ops::BitAnd for SDL_PenInputFlags {
231    type Output = Self;
232
233    #[inline(always)]
234    fn bitand(self, rhs: Self) -> Self::Output {
235        Self(self.0 & rhs.0)
236    }
237}
238
239impl ::core::ops::BitAndAssign for SDL_PenInputFlags {
240    #[inline(always)]
241    fn bitand_assign(&mut self, rhs: Self) {
242        self.0 &= rhs.0;
243    }
244}
245
246impl ::core::ops::BitOr for SDL_PenInputFlags {
247    type Output = Self;
248
249    #[inline(always)]
250    fn bitor(self, rhs: Self) -> Self::Output {
251        Self(self.0 | rhs.0)
252    }
253}
254
255impl ::core::ops::BitOrAssign for SDL_PenInputFlags {
256    #[inline(always)]
257    fn bitor_assign(&mut self, rhs: Self) {
258        self.0 |= rhs.0;
259    }
260}
261
262impl ::core::ops::BitXor for SDL_PenInputFlags {
263    type Output = Self;
264
265    #[inline(always)]
266    fn bitxor(self, rhs: Self) -> Self::Output {
267        Self(self.0 ^ rhs.0)
268    }
269}
270
271impl ::core::ops::BitXorAssign for SDL_PenInputFlags {
272    #[inline(always)]
273    fn bitxor_assign(&mut self, rhs: Self) {
274        self.0 ^= rhs.0;
275    }
276}
277
278impl ::core::ops::Not for SDL_PenInputFlags {
279    type Output = Self;
280
281    #[inline(always)]
282    fn not(self) -> Self::Output {
283        Self(!self.0)
284    }
285}
286
287impl SDL_PenInputFlags {
288    /// pen is pressed down
289    pub const DOWN: Self = Self((1_u32 as Uint32));
290    /// button 1 is pressed
291    pub const BUTTON_1: Self = Self((2_u32 as Uint32));
292    /// button 2 is pressed
293    pub const BUTTON_2: Self = Self((4_u32 as Uint32));
294    /// button 3 is pressed
295    pub const BUTTON_3: Self = Self((8_u32 as Uint32));
296    /// button 4 is pressed
297    pub const BUTTON_4: Self = Self((16_u32 as Uint32));
298    /// button 5 is pressed
299    pub const BUTTON_5: Self = Self((32_u32 as Uint32));
300    /// eraser tip is used
301    pub const ERASER_TIP: Self = Self((1073741824_u32 as Uint32));
302    /// pen is in proximity (since SDL 3.4.0)
303    pub const IN_PROXIMITY: Self = Self((2147483648_u32 as Uint32));
304}
305
306/// pen is pressed down
307pub const SDL_PEN_INPUT_DOWN: SDL_PenInputFlags = SDL_PenInputFlags::DOWN;
308/// button 1 is pressed
309pub const SDL_PEN_INPUT_BUTTON_1: SDL_PenInputFlags = SDL_PenInputFlags::BUTTON_1;
310/// button 2 is pressed
311pub const SDL_PEN_INPUT_BUTTON_2: SDL_PenInputFlags = SDL_PenInputFlags::BUTTON_2;
312/// button 3 is pressed
313pub const SDL_PEN_INPUT_BUTTON_3: SDL_PenInputFlags = SDL_PenInputFlags::BUTTON_3;
314/// button 4 is pressed
315pub const SDL_PEN_INPUT_BUTTON_4: SDL_PenInputFlags = SDL_PenInputFlags::BUTTON_4;
316/// button 5 is pressed
317pub const SDL_PEN_INPUT_BUTTON_5: SDL_PenInputFlags = SDL_PenInputFlags::BUTTON_5;
318/// eraser tip is used
319pub const SDL_PEN_INPUT_ERASER_TIP: SDL_PenInputFlags = SDL_PenInputFlags::ERASER_TIP;
320/// pen is in proximity (since SDL 3.4.0)
321pub const SDL_PEN_INPUT_IN_PROXIMITY: SDL_PenInputFlags = SDL_PenInputFlags::IN_PROXIMITY;
322
323#[cfg(feature = "metadata")]
324impl sdl3_sys::metadata::GroupMetadata for SDL_PenInputFlags {
325    const GROUP_METADATA: &'static sdl3_sys::metadata::Group =
326        &crate::metadata::pen::METADATA_SDL_PenInputFlags;
327}
328
329/// Pen axis indices.
330///
331/// These are the valid values for the `axis` field in [`SDL_PenAxisEvent`]. All
332/// axes are either normalised to 0..1 or report a (positive or negative) angle
333/// in degrees, with 0.0 representing the centre. Not all pens/backends support
334/// all axes: unsupported axes are always zero.
335///
336/// To convert angles for tilt and rotation into vector representation, use
337/// [`SDL_sinf`] on the XTILT, YTILT, or ROTATION component, for example:
338///
339/// `SDL_sinf(xtilt * SDL_PI_F / 180.0)`.
340///
341/// ## Availability
342/// This enum is available since SDL 3.2.0.
343///
344/// ## Known values (`sdl3-sys`)
345/// | Associated constant | Global constant | Description |
346/// | ------------------- | --------------- | ----------- |
347/// | [`PRESSURE`](SDL_PenAxis::PRESSURE) | [`SDL_PEN_AXIS_PRESSURE`] | Pen pressure.  Unidirectional: 0 to 1.0 |
348/// | [`XTILT`](SDL_PenAxis::XTILT) | [`SDL_PEN_AXIS_XTILT`] | Pen horizontal tilt angle.  Bidirectional: -90.0 to 90.0 (left-to-right). |
349/// | [`YTILT`](SDL_PenAxis::YTILT) | [`SDL_PEN_AXIS_YTILT`] | Pen vertical tilt angle.  Bidirectional: -90.0 to 90.0 (top-to-down). |
350/// | [`DISTANCE`](SDL_PenAxis::DISTANCE) | [`SDL_PEN_AXIS_DISTANCE`] | Pen distance to drawing surface.  Unidirectional: 0.0 to 1.0 |
351/// | [`ROTATION`](SDL_PenAxis::ROTATION) | [`SDL_PEN_AXIS_ROTATION`] | Pen barrel rotation.  Bidirectional: -180 to 179.9 (clockwise, 0 is facing up, -180.0 is facing down). |
352/// | [`SLIDER`](SDL_PenAxis::SLIDER) | [`SDL_PEN_AXIS_SLIDER`] | Pen finger wheel or slider (e.g., Airbrush Pen).  Unidirectional: 0 to 1.0 |
353/// | [`TANGENTIAL_PRESSURE`](SDL_PenAxis::TANGENTIAL_PRESSURE) | [`SDL_PEN_AXIS_TANGENTIAL_PRESSURE`] | Pressure from squeezing the pen ("barrel pressure"). |
354/// | [`COUNT`](SDL_PenAxis::COUNT) | [`SDL_PEN_AXIS_COUNT`] | Total known pen axis types in this version of SDL. This number may grow in future releases! |
355#[repr(transparent)]
356#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
357pub struct SDL_PenAxis(pub ::core::ffi::c_int);
358
359impl ::core::cmp::PartialEq<::core::ffi::c_int> for SDL_PenAxis {
360    #[inline(always)]
361    fn eq(&self, other: &::core::ffi::c_int) -> bool {
362        &self.0 == other
363    }
364}
365
366impl ::core::cmp::PartialEq<SDL_PenAxis> for ::core::ffi::c_int {
367    #[inline(always)]
368    fn eq(&self, other: &SDL_PenAxis) -> bool {
369        self == &other.0
370    }
371}
372
373impl From<SDL_PenAxis> for ::core::ffi::c_int {
374    #[inline(always)]
375    fn from(value: SDL_PenAxis) -> Self {
376        value.0
377    }
378}
379
380#[cfg(feature = "debug-impls")]
381impl ::core::fmt::Debug for SDL_PenAxis {
382    fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
383        #[allow(unreachable_patterns)]
384        f.write_str(match *self {
385            Self::PRESSURE => "SDL_PEN_AXIS_PRESSURE",
386            Self::XTILT => "SDL_PEN_AXIS_XTILT",
387            Self::YTILT => "SDL_PEN_AXIS_YTILT",
388            Self::DISTANCE => "SDL_PEN_AXIS_DISTANCE",
389            Self::ROTATION => "SDL_PEN_AXIS_ROTATION",
390            Self::SLIDER => "SDL_PEN_AXIS_SLIDER",
391            Self::TANGENTIAL_PRESSURE => "SDL_PEN_AXIS_TANGENTIAL_PRESSURE",
392            Self::COUNT => "SDL_PEN_AXIS_COUNT",
393
394            _ => return write!(f, "SDL_PenAxis({})", self.0),
395        })
396    }
397}
398
399impl SDL_PenAxis {
400    /// Pen pressure.  Unidirectional: 0 to 1.0
401    pub const PRESSURE: Self = Self((0 as ::core::ffi::c_int));
402    /// Pen horizontal tilt angle.  Bidirectional: -90.0 to 90.0 (left-to-right).
403    pub const XTILT: Self = Self((1 as ::core::ffi::c_int));
404    /// Pen vertical tilt angle.  Bidirectional: -90.0 to 90.0 (top-to-down).
405    pub const YTILT: Self = Self((2 as ::core::ffi::c_int));
406    /// Pen distance to drawing surface.  Unidirectional: 0.0 to 1.0
407    pub const DISTANCE: Self = Self((3 as ::core::ffi::c_int));
408    /// Pen barrel rotation.  Bidirectional: -180 to 179.9 (clockwise, 0 is facing up, -180.0 is facing down).
409    pub const ROTATION: Self = Self((4 as ::core::ffi::c_int));
410    /// Pen finger wheel or slider (e.g., Airbrush Pen).  Unidirectional: 0 to 1.0
411    pub const SLIDER: Self = Self((5 as ::core::ffi::c_int));
412    /// Pressure from squeezing the pen ("barrel pressure").
413    pub const TANGENTIAL_PRESSURE: Self = Self((6 as ::core::ffi::c_int));
414    /// Total known pen axis types in this version of SDL. This number may grow in future releases!
415    pub const COUNT: Self = Self((7 as ::core::ffi::c_int));
416}
417
418/// Pen pressure.  Unidirectional: 0 to 1.0
419pub const SDL_PEN_AXIS_PRESSURE: SDL_PenAxis = SDL_PenAxis::PRESSURE;
420/// Pen horizontal tilt angle.  Bidirectional: -90.0 to 90.0 (left-to-right).
421pub const SDL_PEN_AXIS_XTILT: SDL_PenAxis = SDL_PenAxis::XTILT;
422/// Pen vertical tilt angle.  Bidirectional: -90.0 to 90.0 (top-to-down).
423pub const SDL_PEN_AXIS_YTILT: SDL_PenAxis = SDL_PenAxis::YTILT;
424/// Pen distance to drawing surface.  Unidirectional: 0.0 to 1.0
425pub const SDL_PEN_AXIS_DISTANCE: SDL_PenAxis = SDL_PenAxis::DISTANCE;
426/// Pen barrel rotation.  Bidirectional: -180 to 179.9 (clockwise, 0 is facing up, -180.0 is facing down).
427pub const SDL_PEN_AXIS_ROTATION: SDL_PenAxis = SDL_PenAxis::ROTATION;
428/// Pen finger wheel or slider (e.g., Airbrush Pen).  Unidirectional: 0 to 1.0
429pub const SDL_PEN_AXIS_SLIDER: SDL_PenAxis = SDL_PenAxis::SLIDER;
430/// Pressure from squeezing the pen ("barrel pressure").
431pub const SDL_PEN_AXIS_TANGENTIAL_PRESSURE: SDL_PenAxis = SDL_PenAxis::TANGENTIAL_PRESSURE;
432/// Total known pen axis types in this version of SDL. This number may grow in future releases!
433pub const SDL_PEN_AXIS_COUNT: SDL_PenAxis = SDL_PenAxis::COUNT;
434
435#[cfg(feature = "metadata")]
436impl sdl3_sys::metadata::GroupMetadata for SDL_PenAxis {
437    const GROUP_METADATA: &'static sdl3_sys::metadata::Group =
438        &crate::metadata::pen::METADATA_SDL_PenAxis;
439}
440
441/// An enum that describes the type of a pen device.
442///
443/// A "direct" device is a pen that touches a graphic display (like an Apple
444/// Pencil on an iPad's screen). "Indirect" devices touch an external tablet
445/// surface that is connected to the machine but is not a display (like a
446/// lower-end Wacom tablet connected over USB).
447///
448/// Apps may use this information to decide if they should draw a cursor; if
449/// the pen is touching the screen directly, a cursor doesn't make sense and
450/// can be in the way, but becomes necessary for indirect devices to know where
451/// on the display they are interacting.
452///
453/// ## Availability
454/// This enum is available since SDL 3.4.0.
455///
456/// ## Known values (`sdl3-sys`)
457/// | Associated constant | Global constant | Description |
458/// | ------------------- | --------------- | ----------- |
459/// | [`INVALID`](SDL_PenDeviceType::INVALID) | [`SDL_PEN_DEVICE_TYPE_INVALID`] | Not a valid pen device. |
460/// | [`UNKNOWN`](SDL_PenDeviceType::UNKNOWN) | [`SDL_PEN_DEVICE_TYPE_UNKNOWN`] | Don't know specifics of this pen. |
461/// | [`DIRECT`](SDL_PenDeviceType::DIRECT) | [`SDL_PEN_DEVICE_TYPE_DIRECT`] | Pen touches display. |
462/// | [`INDIRECT`](SDL_PenDeviceType::INDIRECT) | [`SDL_PEN_DEVICE_TYPE_INDIRECT`] | Pen touches something that isn't the display. |
463#[repr(transparent)]
464#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
465pub struct SDL_PenDeviceType(pub ::core::ffi::c_int);
466
467impl ::core::cmp::PartialEq<::core::ffi::c_int> for SDL_PenDeviceType {
468    #[inline(always)]
469    fn eq(&self, other: &::core::ffi::c_int) -> bool {
470        &self.0 == other
471    }
472}
473
474impl ::core::cmp::PartialEq<SDL_PenDeviceType> for ::core::ffi::c_int {
475    #[inline(always)]
476    fn eq(&self, other: &SDL_PenDeviceType) -> bool {
477        self == &other.0
478    }
479}
480
481impl From<SDL_PenDeviceType> for ::core::ffi::c_int {
482    #[inline(always)]
483    fn from(value: SDL_PenDeviceType) -> Self {
484        value.0
485    }
486}
487
488#[cfg(feature = "debug-impls")]
489impl ::core::fmt::Debug for SDL_PenDeviceType {
490    fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
491        #[allow(unreachable_patterns)]
492        f.write_str(match *self {
493            Self::INVALID => "SDL_PEN_DEVICE_TYPE_INVALID",
494            Self::UNKNOWN => "SDL_PEN_DEVICE_TYPE_UNKNOWN",
495            Self::DIRECT => "SDL_PEN_DEVICE_TYPE_DIRECT",
496            Self::INDIRECT => "SDL_PEN_DEVICE_TYPE_INDIRECT",
497
498            _ => return write!(f, "SDL_PenDeviceType({})", self.0),
499        })
500    }
501}
502
503impl SDL_PenDeviceType {
504    /// Not a valid pen device.
505    pub const INVALID: Self = Self((-1_i32 as ::core::ffi::c_int));
506    /// Don't know specifics of this pen.
507    pub const UNKNOWN: Self = Self((0_i32 as ::core::ffi::c_int));
508    /// Pen touches display.
509    pub const DIRECT: Self = Self((1_i32 as ::core::ffi::c_int));
510    /// Pen touches something that isn't the display.
511    pub const INDIRECT: Self = Self((2_i32 as ::core::ffi::c_int));
512}
513
514/// Not a valid pen device.
515pub const SDL_PEN_DEVICE_TYPE_INVALID: SDL_PenDeviceType = SDL_PenDeviceType::INVALID;
516/// Don't know specifics of this pen.
517pub const SDL_PEN_DEVICE_TYPE_UNKNOWN: SDL_PenDeviceType = SDL_PenDeviceType::UNKNOWN;
518/// Pen touches display.
519pub const SDL_PEN_DEVICE_TYPE_DIRECT: SDL_PenDeviceType = SDL_PenDeviceType::DIRECT;
520/// Pen touches something that isn't the display.
521pub const SDL_PEN_DEVICE_TYPE_INDIRECT: SDL_PenDeviceType = SDL_PenDeviceType::INDIRECT;
522
523#[cfg(feature = "metadata")]
524impl sdl3_sys::metadata::GroupMetadata for SDL_PenDeviceType {
525    const GROUP_METADATA: &'static sdl3_sys::metadata::Group =
526        &crate::metadata::pen::METADATA_SDL_PenDeviceType;
527}
528
529unsafe extern "C" {
530    /// Get the device type of the given pen.
531    ///
532    /// Many platforms do not supply this information, so an app must always be
533    /// prepared to get an [`SDL_PEN_DEVICE_TYPE_UNKNOWN`] result.
534    ///
535    /// ## Parameters
536    /// - `instance_id`: the pen instance ID.
537    ///
538    /// ## Return value
539    /// Returns the device type of the given pen, or [`SDL_PEN_DEVICE_TYPE_INVALID`]
540    ///   on failure; call [`SDL_GetError()`] for more information.
541    ///
542    /// ## Thread safety
543    /// It is safe to call this function from any thread.
544    ///
545    /// ## Availability
546    /// This function is available since SDL 3.4.0.
547    pub fn SDL_GetPenDeviceType(instance_id: SDL_PenID) -> SDL_PenDeviceType;
548}
549
550#[cfg(doc)]
551use crate::everything::*;