Skip to content

Commit

Permalink
wayland: implement wl_touch
Browse files Browse the repository at this point in the history
  • Loading branch information
Sporif committed May 5, 2024
1 parent 7606585 commit ccdee69
Show file tree
Hide file tree
Showing 22 changed files with 939 additions and 46 deletions.
4 changes: 1 addition & 3 deletions docs/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ Jay supports the following wayland protocols:
| ext_session_lock_manager_v1 | 1 | Yes |
| ext_transient_seat_manager_v1 | 1[^ts_rejected] | Yes |
| org_kde_kwin_server_decoration_manager | 1 | |
| wl_compositor | 6[^no_touch] | |
| wl_compositor | 6 | |
| wl_data_device_manager | 3 | |
| wl_drm | 2 | |
| wl_output | 4 | |
Expand Down Expand Up @@ -171,7 +171,6 @@ Jay supports the following wayland protocols:
| zxdg_decoration_manager_v1 | 1 | |
| zxdg_output_manager_v1 | 3 | |

[^no_touch]: Touch input is not supported.
[^no_tearing]: Tearing screen updates are not supported.
[^no_exclusive]: Exclusive zones are not supported.
[^lsaccess]: Sandboxes can restrict access to this protocol.
Expand All @@ -182,5 +181,4 @@ Jay supports the following wayland protocols:
The following features are currently not supported but might get implemented in the future:

- Fine-grained damage tracking.
- Touch support.
- Tearing updates of fullscreen games.
23 changes: 23 additions & 0 deletions src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,23 @@ pub enum KeyState {
Pressed,
}

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct TouchPosition {
pub x: Fixed,
pub y: Fixed,
pub x_transformed: Fixed,
pub y_transformed: Fixed,
}

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum TouchEvent {
Down { pos: TouchPosition },
Up,
Motion { pos: TouchPosition },
Cancel,
Frame,
}

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum ScrollAxis {
Horizontal = HORIZONTAL_SCROLL as _,
Expand Down Expand Up @@ -272,6 +289,12 @@ pub enum InputEvent {
state: KeyState,
},

Touch {
seat_slot: i32,
time_usec: u64,
event: TouchEvent,
},

AxisPx {
dist: Fixed,
axis: ScrollAxis,
Expand Down
64 changes: 63 additions & 1 deletion src/backends/metal/input.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use {
crate::{
backend::{AxisSource, InputEvent, KeyState, ScrollAxis},
backend::{AxisSource, InputEvent, KeyState, ScrollAxis, TouchEvent, TouchPosition},
backends::metal::MetalBackend,
fixed::Fixed,
ifs::wl_seat::tablet::{
Expand Down Expand Up @@ -121,6 +121,11 @@ impl MetalBackend {
c::LIBINPUT_EVENT_TABLET_PAD_BUTTON => self.handle_tablet_pad_button(event),
c::LIBINPUT_EVENT_TABLET_PAD_RING => self.handle_tablet_pad_ring(event),
c::LIBINPUT_EVENT_TABLET_PAD_STRIP => self.handle_tablet_pad_strip(event),
c::LIBINPUT_EVENT_TOUCH_DOWN => self.handle_touch_down(event),
c::LIBINPUT_EVENT_TOUCH_UP => self.handle_touch_up(event),
c::LIBINPUT_EVENT_TOUCH_MOTION => self.handle_touch_motion(event),
c::LIBINPUT_EVENT_TOUCH_CANCEL => self.handle_touch_cancel(event),
c::LIBINPUT_EVENT_TOUCH_FRAME => self.handle_touch_frame(event),
_ => {}
}
}
Expand Down Expand Up @@ -545,4 +550,61 @@ impl MetalBackend {
},
});
}

fn handle_touch_down(self: &Rc<Self>, event: LibInputEvent) {
let (event, dev) = unpack!(self, event, touch_event);
let pos = TouchPosition {
x: Fixed::from_f64(event.x()),
y: Fixed::from_f64(event.y()),
x_transformed: Fixed::from_f64(event.x_transformed(1)),
y_transformed: Fixed::from_f64(event.y_transformed(1)),
};
dev.event(InputEvent::Touch {
seat_slot: event.seat_slot(),
time_usec: event.time_usec(),
event: TouchEvent::Down { pos },
})
}

fn handle_touch_up(self: &Rc<Self>, event: LibInputEvent) {
let (event, dev) = unpack!(self, event, touch_event);
dev.event(InputEvent::Touch {
seat_slot: event.seat_slot(),
time_usec: event.time_usec(),
event: TouchEvent::Up,
})
}

fn handle_touch_motion(self: &Rc<Self>, event: LibInputEvent) {
let (event, dev) = unpack!(self, event, touch_event);
let pos = TouchPosition {
x: Fixed::from_f64(event.x()),
y: Fixed::from_f64(event.y()),
x_transformed: Fixed::from_f64(event.x_transformed(1)),
y_transformed: Fixed::from_f64(event.y_transformed(1)),
};
dev.event(InputEvent::Touch {
seat_slot: event.seat_slot(),
time_usec: event.time_usec(),
event: TouchEvent::Motion { pos },
})
}

fn handle_touch_cancel(self: &Rc<Self>, event: LibInputEvent) {
let (event, dev) = unpack!(self, event, touch_event);
dev.event(InputEvent::Touch {
seat_slot: event.seat_slot(),
time_usec: event.time_usec(),
event: TouchEvent::Cancel,
})
}

fn handle_touch_frame(self: &Rc<Self>, event: LibInputEvent) {
let (event, dev) = unpack!(self, event, touch_event);
dev.event(InputEvent::Touch {
seat_slot: 0,
time_usec: event.time_usec(),
event: TouchEvent::Frame,
})
}
}
60 changes: 59 additions & 1 deletion src/cli/seat_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ use {
TabletPadStripSource, TabletPadStripStop, TabletToolButton, TabletToolDistance,
TabletToolDown, TabletToolFrame, TabletToolMotion, TabletToolPressure,
TabletToolProximityIn, TabletToolProximityOut, TabletToolRotation,
TabletToolSlider, TabletToolTilt, TabletToolUp, TabletToolWheel,
TabletToolSlider, TabletToolTilt, TabletToolUp, TabletToolWheel, TouchCancel,
TouchDown, TouchFrame, TouchMotion, TouchUp,
},
},
},
Expand Down Expand Up @@ -583,6 +584,63 @@ async fn run(seat_test: Rc<SeatTest>) {
}
println!();
});
let st = seat_test.clone();
TouchDown::handle(tc, se, (), move |_, ev| {
if all || ev.seat == seat {
if all {
print!("Seat: {}, ", st.name(ev.seat));
}
println!(
"Time: {:.4}, Touch: {}, Down: {}x{}",
time(ev.time_usec),
ev.id,
ev.x,
ev.y
);
}
});
let st = seat_test.clone();
TouchUp::handle(tc, se, (), move |_, ev| {
if all || ev.seat == seat {
if all {
print!("Seat: {}, ", st.name(ev.seat));
}
println!("Time: {:.4}, Touch: {}, Up", time(ev.time_usec), ev.id);
}
});
let st = seat_test.clone();
TouchMotion::handle(tc, se, (), move |_, ev| {
if all || ev.seat == seat {
if all {
print!("Seat: {}, ", st.name(ev.seat));
}
println!(
"Time: {:.4}, Touch: {} Motion: {}x{}",
time(ev.time_usec),
ev.id,
ev.x,
ev.y
);
}
});
let st = seat_test.clone();
TouchFrame::handle(tc, se, (), move |_, ev| {
if all || ev.seat == seat {
if all {
print!("Seat: {}, ", st.name(ev.seat));
}
println!("Time: {:.4}, Touch: {}, Frame", time(ev.time_usec), ev.id);
}
});
let st = seat_test.clone();
TouchCancel::handle(tc, se, (), move |_, ev| {
if all || ev.seat == seat {
if all {
print!("Seat: {}, ", st.name(ev.seat));
}
println!("Time: {:.4}, Touch: {}, Cancel", time(ev.time_usec), ev.id);
}
});
pending::<()>().await;
}

Expand Down
1 change: 1 addition & 0 deletions src/compositor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ fn start_compositor2(
connector_ids: Default::default(),
root: Rc::new(DisplayNode::new(node_ids.next())),
workspaces: Default::default(),
builtin_output: Default::default(),
dummy_output: Default::default(),
node_ids,
backend_events: AsyncQueue::new(),
Expand Down
51 changes: 50 additions & 1 deletion src/ifs/jay_seat_events.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use {
crate::{
backend::{InputDeviceId, KeyState},
backend::{InputDeviceId, KeyState, TouchEvent},
client::Client,
fixed::Fixed,
ifs::wl_seat::{
Expand Down Expand Up @@ -468,6 +468,55 @@ impl JaySeatEvents {
ring,
});
}

pub fn send_touch(&self, seat: SeatId, time_usec: u64, id: i32, event: TouchEvent) {
match event {
TouchEvent::Down { pos } => {
self.client.event(TouchDown {
self_id: self.id,
seat: seat.raw(),
time_usec,
id,
x: pos.x_transformed,
y: pos.y_transformed,
});
}
TouchEvent::Up => {
self.client.event(TouchUp {
self_id: self.id,
seat: seat.raw(),
time_usec,
id,
});
}
TouchEvent::Motion { pos } => {
self.client.event(TouchMotion {
self_id: self.id,
seat: seat.raw(),
time_usec,
id,
x: pos.x_transformed,
y: pos.y_transformed,
});
}
TouchEvent::Frame => {
self.client.event(TouchFrame {
self_id: self.id,
seat: seat.raw(),
time_usec,
id,
});
}
TouchEvent::Cancel => {
self.client.event(TouchCancel {
self_id: self.id,
seat: seat.raw(),
time_usec,
id,
});
}
}
}
}

impl JaySeatEventsRequestHandler for JaySeatEvents {
Expand Down
Loading

0 comments on commit ccdee69

Please sign in to comment.