1
0
Fork 0
forked from wry/wry

tablet: implement version 2

This commit is contained in:
Julian Orth 2025-04-22 22:22:31 +02:00
parent 1d017ec2c2
commit dee0066f1a
25 changed files with 426 additions and 31 deletions

View file

@ -470,6 +470,27 @@ impl JaySeatEvents {
});
}
pub fn send_tablet_pad_dial(
&self,
seat: SeatId,
pad: InputDeviceId,
time_usec: u64,
value120: i32,
dial: u32,
) {
self.client.event(TabletPadDialDelta {
self_id: self.id,
value120,
});
self.client.event(TabletPadDialFrame {
self_id: self.id,
seat: seat.raw(),
time_usec,
input_device: pad.raw(),
dial,
});
}
pub fn send_touch_down(&self, seat: SeatId, time_usec: u64, id: i32, x: Fixed, y: Fixed) {
self.client.event(TouchDown {
self_id: self.id,

View file

@ -266,6 +266,7 @@ impl WlSeatGlobal {
| InputEvent::TabletPadModeSwitch { time_usec, .. }
| InputEvent::TabletPadRing { time_usec, .. }
| InputEvent::TabletPadStrip { time_usec, .. }
| InputEvent::TabletPadDial { time_usec, .. }
| InputEvent::TouchFrame { time_usec, .. } => {
self.last_input_usec.set(time_usec);
if self.idle_notifications.is_not_empty() {
@ -314,6 +315,7 @@ impl WlSeatGlobal {
InputEvent::TabletPadModeSwitch { .. } => {}
InputEvent::TabletPadRing { .. } => {}
InputEvent::TabletPadStrip { .. } => {}
InputEvent::TabletPadDial { .. } => {}
InputEvent::TouchDown { .. } => {}
InputEvent::TouchUp { .. } => {}
InputEvent::TouchMotion { .. } => {}
@ -458,6 +460,12 @@ impl WlSeatGlobal {
source,
position,
} => self.tablet_event_pad_strip(pad, strip, source, position, time_usec),
InputEvent::TabletPadDial {
time_usec,
pad,
dial,
value120,
} => self.tablet_event_pad_dial(pad, dial, value120, time_usec),
InputEvent::TouchDown {
time_usec,
id,

View file

@ -7,7 +7,8 @@ use {
WlSeatGlobal,
tablet::{
pad_owner::PadOwnerHolder, tablet_bindings::TabletBindings,
tool_owner::ToolOwnerHolder, zwp_tablet_pad_group_v2::ZwpTabletPadGroupV2,
tool_owner::ToolOwnerHolder, zwp_tablet_pad_dial_v2::ZwpTabletPadDialV2,
zwp_tablet_pad_group_v2::ZwpTabletPadGroupV2,
zwp_tablet_pad_ring_v2::ZwpTabletPadRingV2,
zwp_tablet_pad_strip_v2::ZwpTabletPadStripV2,
zwp_tablet_pad_v2::ZwpTabletPadV2, zwp_tablet_seat_v2::ZwpTabletSeatV2,
@ -35,6 +36,7 @@ mod tablet_bindings;
mod tool;
pub mod tool_owner;
pub mod zwp_tablet_manager_v2;
pub mod zwp_tablet_pad_dial_v2;
pub mod zwp_tablet_pad_group_v2;
pub mod zwp_tablet_pad_ring_v2;
pub mod zwp_tablet_pad_strip_v2;
@ -58,6 +60,7 @@ pub struct TabletInit {
pub name: String,
pub pid: u32,
pub vid: u32,
pub bustype: Option<u32>,
pub path: String,
}
@ -79,6 +82,7 @@ pub struct TabletPadInit {
pub buttons: u32,
pub strips: u32,
pub rings: u32,
pub dials: u32,
pub groups: Vec<TabletPadGroupInit>,
}
@ -87,6 +91,7 @@ pub struct TabletPadGroupInit {
pub buttons: Vec<u32>,
pub rings: Vec<u32>,
pub strips: Vec<u32>,
pub dials: Vec<u32>,
pub modes: u32,
pub mode: u32,
}
@ -112,6 +117,7 @@ pub struct Tablet {
name: String,
pid: u32,
vid: u32,
bustype: Option<u32>,
path: String,
bindings: TabletBindings<ZwpTabletV2>,
tools: CopyHashMap<TabletToolId, Rc<TabletTool>>,
@ -186,6 +192,7 @@ pub struct TabletPad {
groups: Vec<Rc<TabletPadGroup>>,
strips: Vec<Rc<TabletPadStrip>>,
rings: Vec<Rc<TabletPadRing>>,
dials: Vec<Rc<TabletPadDial>>,
node: CloneCell<Rc<dyn Node>>,
pub(super) pad_owner: PadOwnerHolder,
}
@ -196,6 +203,7 @@ pub struct TabletPadGroup {
modes: u32,
rings: Vec<u32>,
strips: Vec<u32>,
dials: Vec<u32>,
bindings: TabletBindings<ZwpTabletPadGroupV2>,
}
@ -207,6 +215,10 @@ pub struct TabletPadRing {
bindings: TabletBindings<ZwpTabletPadRingV2>,
}
pub struct TabletPadDial {
bindings: TabletBindings<ZwpTabletPadDialV2>,
}
#[derive(Copy, Clone, Debug)]
pub enum TabletRingEventSource {
Finger,
@ -269,6 +281,7 @@ impl WlSeatGlobal {
name: init.name.clone(),
pid: init.pid,
vid: init.vid,
bustype: init.bustype,
path: init.path.clone(),
bindings: Default::default(),
tools: Default::default(),
@ -319,6 +332,9 @@ impl WlSeatGlobal {
for strips in &pad.strips {
strips.bindings.clear();
}
for dials in &pad.dials {
dials.bindings.clear();
}
}
}

View file

@ -6,9 +6,10 @@ use {
wl_seat::{
WlSeatGlobal,
tablet::{
PadButtonState, TabletPad, TabletPadGroup, TabletPadId, TabletPadInit,
TabletPadRing, TabletPadStrip, TabletRingEventSource, TabletStripEventSource,
normalizeu, zwp_tablet_pad_v2::ZwpTabletPadV2, zwp_tablet_v2::ZwpTabletV2,
PadButtonState, TabletPad, TabletPadDial, TabletPadGroup, TabletPadId,
TabletPadInit, TabletPadRing, TabletPadStrip, TabletRingEventSource,
TabletStripEventSource, normalizeu, zwp_tablet_pad_v2::ZwpTabletPadV2,
zwp_tablet_v2::ZwpTabletV2,
},
},
wl_surface::WlSurface,
@ -33,6 +34,12 @@ impl WlSeatGlobal {
bindings: Default::default(),
}));
}
let mut dials = Vec::new();
for _ in 0..init.dials {
dials.push(Rc::new(TabletPadDial {
bindings: Default::default(),
}));
}
let mut groups = Vec::new();
for group_init in &init.groups {
groups.push(Rc::new(TabletPadGroup {
@ -41,6 +48,7 @@ impl WlSeatGlobal {
modes: group_init.modes,
rings: group_init.rings.clone(),
strips: group_init.strips.clone(),
dials: group_init.dials.clone(),
bindings: Default::default(),
}));
}
@ -56,6 +64,7 @@ impl WlSeatGlobal {
groups,
strips,
rings,
dials,
node: CloneCell::new(self.state.root.clone()),
pad_owner: Default::default(),
});
@ -161,6 +170,26 @@ impl WlSeatGlobal {
}
}
}
pub fn tablet_event_pad_dial(
self: &Rc<Self>,
pad: TabletPadId,
dial: u32,
value120: i32,
time_usec: u64,
) {
if let Some(pad) = self.tablet.pads.get(&pad) {
self.state.for_each_seat_tester(|t| {
t.send_tablet_pad_dial(self.id, pad.dev, time_usec, value120, dial)
});
if pad.tablet.is_some() {
if let Some(dial) = pad.dials.get(dial as usize) {
let node = self.keyboard_node.get();
node.node_on_tablet_pad_dial(&pad, dial, value120, time_usec);
}
}
}
}
}
impl TabletPad {
@ -235,6 +264,22 @@ impl TabletPad {
});
}
pub fn surface_dial(
self: &Rc<Self>,
n: &WlSurface,
dial: &Rc<TabletPadDial>,
value120: i32,
time_usec: u64,
) {
let time = usec_to_msec(time_usec);
self.seat.tablet_for_each_seat(n, |s| {
if let Some(dial) = dial.bindings.get(&s) {
dial.send_delta(value120);
dial.send_frame(time);
}
});
}
pub fn surface_strip(
self: &Rc<Self>,
n: &WlSurface,

View file

@ -57,7 +57,7 @@ impl Global for ZwpTabletManagerV2Global {
}
fn version(&self) -> u32 {
1
2
}
}

View file

@ -0,0 +1,74 @@
use {
crate::{
client::{Client, ClientError},
ifs::wl_seat::tablet::{TabletPadDial, zwp_tablet_seat_v2::ZwpTabletSeatV2},
leaks::Tracker,
object::{Object, Version},
wire::{ZwpTabletPadDialV2Id, zwp_tablet_pad_dial_v2::*},
},
std::rc::Rc,
thiserror::Error,
};
pub struct ZwpTabletPadDialV2 {
pub id: ZwpTabletPadDialV2Id,
pub client: Rc<Client>,
pub tracker: Tracker<Self>,
pub version: Version,
pub seat: Rc<ZwpTabletSeatV2>,
pub dial: Rc<TabletPadDial>,
}
impl ZwpTabletPadDialV2 {
pub fn detach(&self) {
self.dial.bindings.remove(&self.seat);
}
pub fn send_delta(&self, value120: i32) {
self.client.event(Delta {
self_id: self.id,
value120,
});
}
pub fn send_frame(&self, time: u32) {
self.client.event(Frame {
self_id: self.id,
time,
});
}
}
impl ZwpTabletPadDialV2RequestHandler for ZwpTabletPadDialV2 {
type Error = ZwpTabletPadDialV2Error;
fn set_feedback(&self, _req: SetFeedback<'_>, _slf: &Rc<Self>) -> Result<(), Self::Error> {
Ok(())
}
fn destroy(&self, _req: Destroy, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.detach();
self.client.remove_obj(self)?;
Ok(())
}
}
object_base! {
self = ZwpTabletPadDialV2;
version = self.version;
}
impl Object for ZwpTabletPadDialV2 {
fn break_loops(&self) {
self.detach();
}
}
simple_add_obj!(ZwpTabletPadDialV2);
#[derive(Debug, Error)]
pub enum ZwpTabletPadDialV2Error {
#[error(transparent)]
ClientError(Box<ClientError>),
}
efrom!(ZwpTabletPadDialV2Error, ClientError);

View file

@ -2,7 +2,8 @@ use {
crate::{
client::{Client, ClientError},
ifs::wl_seat::tablet::{
TabletPadGroup, zwp_tablet_pad_ring_v2::ZwpTabletPadRingV2,
TabletPadGroup, zwp_tablet_pad_dial_v2::ZwpTabletPadDialV2,
zwp_tablet_pad_ring_v2::ZwpTabletPadRingV2,
zwp_tablet_pad_strip_v2::ZwpTabletPadStripV2, zwp_tablet_seat_v2::ZwpTabletSeatV2,
},
leaks::Tracker,
@ -48,6 +49,13 @@ impl ZwpTabletPadGroupV2 {
});
}
pub fn send_dial(&self, dial: &ZwpTabletPadDialV2) {
self.client.event(Dial {
self_id: self.id,
dial: dial.id,
});
}
pub fn send_modes(&self, modes: u32) {
self.client.event(Modes {
self_id: self.id,

View file

@ -4,7 +4,8 @@ use {
ifs::wl_seat::{
WlSeatGlobal,
tablet::{
Tablet, TabletPad, TabletTool, zwp_tablet_pad_group_v2::ZwpTabletPadGroupV2,
Tablet, TabletPad, TabletTool, zwp_tablet_pad_dial_v2::ZwpTabletPadDialV2,
zwp_tablet_pad_group_v2::ZwpTabletPadGroupV2,
zwp_tablet_pad_ring_v2::ZwpTabletPadRingV2,
zwp_tablet_pad_strip_v2::ZwpTabletPadStripV2, zwp_tablet_pad_v2::ZwpTabletPadV2,
zwp_tablet_tool_v2::ZwpTabletToolV2, zwp_tablet_v2::ZwpTabletV2,
@ -18,6 +19,9 @@ use {
thiserror::Error,
};
const BUSTYPE_SINCE: Version = Version(2);
const DIALS_SINCE: Version = Version(2);
pub struct ZwpTabletSeatV2 {
pub id: ZwpTabletSeatV2Id,
pub client: Rc<Client>,
@ -53,6 +57,11 @@ impl ZwpTabletSeatV2 {
obj.send_name(&tablet.name);
obj.send_id(tablet.vid, tablet.pid);
obj.send_path(&tablet.path);
if obj.version >= BUSTYPE_SINCE {
if let Some(bustype) = tablet.bustype {
obj.send_bustype(bustype);
}
}
obj.send_done();
tablet.bindings.add(self, &obj);
}
@ -161,6 +170,25 @@ impl ZwpTabletSeatV2 {
group_obj.send_strip(&strip_obj);
strip.bindings.add(self, &strip_obj);
}
if self.version >= DIALS_SINCE {
for dial in &group.dials {
let Some(dial) = pad.dials.get(*dial as usize) else {
continue;
};
let dial_obj = Rc::new(ZwpTabletPadDialV2 {
id: id!(),
client: self.client.clone(),
seat: self.clone(),
tracker: Default::default(),
version: self.version,
dial: dial.clone(),
});
track!(self.client, dial_obj);
self.client.add_server_obj(&dial_obj);
group_obj.send_dial(&dial_obj);
dial.bindings.add(self, &dial_obj);
}
}
group_obj.send_done();
}
obj.send_done();

View file

@ -53,6 +53,13 @@ impl ZwpTabletV2 {
pub fn send_removed(&self) {
self.client.event(Removed { self_id: self.id });
}
pub fn send_bustype(&self, bustype: u32) {
self.client.event(Bustype {
self_id: self.id,
bustype,
});
}
}
impl ZwpTabletV2RequestHandler for ZwpTabletV2 {

View file

@ -39,9 +39,9 @@ use {
wl_seat::{
Dnd, NodeSeatState, SeatId, WlSeatGlobal,
tablet::{
PadButtonState, TabletPad, TabletPadGroup, TabletPadRing, TabletPadStrip,
TabletRingEventSource, TabletStripEventSource, TabletTool, TabletToolChanges,
ToolButtonState,
PadButtonState, TabletPad, TabletPadDial, TabletPadGroup, TabletPadRing,
TabletPadStrip, TabletRingEventSource, TabletStripEventSource, TabletTool,
TabletToolChanges, ToolButtonState,
},
text_input::TextInputConnection,
wl_pointer::PendingScroll,
@ -2016,6 +2016,16 @@ impl Node for WlSurface {
pad.surface_strip(self, strip, source, position, time_usec);
}
fn node_on_tablet_pad_dial(
&self,
pad: &Rc<TabletPad>,
dial: &Rc<TabletPadDial>,
value120: i32,
time_usec: u64,
) {
pad.surface_dial(self, dial, value120, time_usec);
}
fn node_on_tablet_tool_leave(&self, tool: &Rc<TabletTool>, time_usec: u64) {
tool.surface_leave(self, time_usec);
}