winit-core:winit: add tablet input support

The API is integrated into the `WindowEvent::Pointer*` API and is
present in form of `TabletTool` variant on corresponding data entries.

For now implemented for Web, Windows, and with limitations for Wayland.

Fixes #99.

Co-authored-by: daxpedda <daxpedda@gmail.com>
This commit is contained in:
Kirill Chibisov 2025-10-07 21:42:36 +09:00 committed by GitHub
parent ffcdf80192
commit f046e778aa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 1206 additions and 204 deletions

View file

@ -1006,6 +1006,15 @@ pub struct Device {
// For master devices, this is the paired device (pointer <-> keyboard).
// For slave devices, this is the master.
pub(crate) attachment: c_int,
pub(crate) r#type: DeviceType,
}
#[derive(Clone, Copy, Debug)]
pub(crate) enum DeviceType {
Mouse,
Touch,
Pen,
Eraser,
}
#[derive(Debug, Copy, Clone)]
@ -1022,9 +1031,10 @@ pub(crate) enum ScrollOrientation {
}
impl Device {
pub(crate) fn new(info: &ffi::XIDeviceInfo) -> Self {
pub(crate) fn new(info: &ffi::XIDeviceInfo, atoms: &Atoms) -> Self {
let name = unsafe { CStr::from_ptr(info.name).to_string_lossy() };
let mut scroll_axes = Vec::new();
let mut r#type = None;
if Device::physical_device(info) {
// Identify scroll axes
@ -1041,12 +1051,34 @@ impl Device {
},
position: 0.0,
}));
} else if ty == ffi::XITouchClass {
r#type = Some(DeviceType::Touch);
} else if r#type.is_none() && ty == ffi::XIValuatorClass {
let info = unsafe { &*(class_ptr as *const ffi::XIValuatorClassInfo) };
let atom = info.label as xproto::Atom;
if atom == atoms[ABS_X]
|| atom == atoms[ABS_Y]
|| atom == atoms[ABS_PRESSURE]
|| atom == atoms[ABS_TILT_X]
|| atom == atoms[ABS_TILT_Y]
{
if name.contains("eraser") {
r#type = Some(DeviceType::Eraser);
} else {
r#type = Some(DeviceType::Pen);
}
}
}
}
}
let mut device =
Device { _name: name.into_owned(), scroll_axes, attachment: info.attachment };
let mut device = Device {
_name: name.into_owned(),
scroll_axes,
attachment: info.attachment,
r#type: r#type.unwrap_or(DeviceType::Mouse),
};
device.reset_scroll_position(info);
device
}