Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wayland: implement wl_touch #230

Merged
merged 1 commit into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions docs/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,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 @@ -179,12 +179,5 @@ Jay supports the following wayland protocols:
| zxdg_decoration_manager_v1 | 1 | |
| zxdg_output_manager_v1 | 3 | |

[^no_touch]: Touch input is not supported.
[^lsaccess]: Sandboxes can restrict access to this protocol.
[^ts_rejected]: Seat creation is always rejected.

## Missing Features

The following features are currently not supported but might get implemented in the future:

- Touch support.
4 changes: 4 additions & 0 deletions jay-config/src/_private/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,10 @@ impl Client {
self.send(&ClientMessage::SetTransformMatrix { device, matrix })
}

pub fn set_calibration_matrix(&self, device: InputDevice, matrix: [[f32; 3]; 2]) {
self.send(&ClientMessage::SetCalibrationMatrix { device, matrix })
}

pub fn set_px_per_wheel_scroll(&self, device: InputDevice, px: f64) {
self.send(&ClientMessage::SetPxPerWheelScroll { device, px })
}
Expand Down
4 changes: 4 additions & 0 deletions jay-config/src/_private/ipc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,10 @@ pub enum ClientMessage<'a> {
connector: Option<Connector>,
mode: TearingMode,
},
SetCalibrationMatrix {
device: InputDevice,
matrix: [[f32; 3]; 2],
},
}

#[derive(Serialize, Deserialize, Debug)]
Expand Down
7 changes: 7 additions & 0 deletions jay-config/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ impl InputDevice {
get!().set_transform_matrix(self, matrix);
}

/// Sets the calibration matrix of the device.
///
/// This corresponds to the libinput setting of the same name.
pub fn set_calibration_matrix(self, matrix: [[f32; 3]; 2]) {
get!().set_calibration_matrix(self, matrix);
}

/// Returns the name of the device.
pub fn name(self) -> String {
get!(String::new()).device_name(self)
Expand Down
1 change: 1 addition & 0 deletions release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
- Add fine-grained damage tracking.
- Add support for adaptive sync.
- Add support for tearing.
- Add support for touch input.

# 1.4.0 (2024-07-07)

Expand Down
27 changes: 27 additions & 0 deletions src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ pub trait InputDevice {
None
}
fn set_transform_matrix(&self, matrix: TransformMatrix);
fn calibration_matrix(&self) -> Option<[[f32; 3]; 2]> {
None
}
fn set_calibration_matrix(&self, m: [[f32; 3]; 2]) {
let _ = m;
}
fn name(&self) -> Rc<String>;
fn dev_t(&self) -> Option<c::dev_t> {
None
Expand Down Expand Up @@ -392,6 +398,27 @@ pub enum InputEvent {
source: Option<TabletStripEventSource>,
position: Option<f64>,
},
TouchDown {
time_usec: u64,
id: i32,
x_normed: Fixed,
y_normed: Fixed,
},
TouchUp {
time_usec: u64,
id: i32,
},
TouchMotion {
time_usec: u64,
id: i32,
x_normed: Fixed,
y_normed: Fixed,
},
TouchCancel {
time_usec: u64,
id: i32,
},
TouchFrame,
}

pub enum DrmEvent {
Expand Down
25 changes: 25 additions & 0 deletions src/backends/metal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ struct InputDeviceProperties {
drag_enabled: Cell<Option<bool>>,
drag_lock_enabled: Cell<Option<bool>>,
natural_scrolling_enabled: Cell<Option<bool>>,
calibration_matrix: Cell<Option<[[f32; 3]; 2]>>,
}

#[derive(Clone)]
Expand Down Expand Up @@ -436,6 +437,9 @@ impl MetalInputDevice {
if let Some(enabled) = self.desired.natural_scrolling_enabled.get() {
self.set_natural_scrolling_enabled(enabled);
}
if let Some(lh) = self.desired.calibration_matrix.get() {
self.set_calibration_matrix(lh);
}
self.fetch_effective();
}

Expand Down Expand Up @@ -465,6 +469,11 @@ impl MetalInputDevice {
.natural_scrolling_enabled
.set(Some(device.natural_scrolling_enabled()));
}
if device.has_calibration_matrix() {
self.effective
.calibration_matrix
.set(Some(device.get_calibration_matrix()));
}
}

fn pre_pause(&self) {
Expand Down Expand Up @@ -721,6 +730,22 @@ impl InputDevice for MetalInputDevice {
groups,
}))
}

fn calibration_matrix(&self) -> Option<[[f32; 3]; 2]> {
self.effective.calibration_matrix.get()
}

fn set_calibration_matrix(&self, m: [[f32; 3]; 2]) {
self.desired.calibration_matrix.set(Some(m));
if let Some(dev) = self.inputdev.get() {
if dev.device().has_calibration_matrix() {
dev.device().set_calibration_matrix(m);
self.effective
.calibration_matrix
.set(Some(dev.device().get_calibration_matrix()));
}
}
}
}

impl MetalInputDevice {
Expand Down
46 changes: 46 additions & 0 deletions src/backends/metal/input.rs
Original file line number Diff line number Diff line change
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 @@ -539,4 +544,45 @@ impl MetalBackend {
},
});
}

fn handle_touch_down(self: &Rc<Self>, event: LibInputEvent) {
let (event, dev) = unpack!(self, event, touch_event);
dev.event(InputEvent::TouchDown {
time_usec: event.time_usec(),
id: event.seat_slot(),
x_normed: Fixed::from_f64(event.x_transformed(1)),
y_normed: Fixed::from_f64(event.y_transformed(1)),
})
}

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

fn handle_touch_motion(self: &Rc<Self>, event: LibInputEvent) {
let (event, dev) = unpack!(self, event, touch_event);
dev.event(InputEvent::TouchMotion {
time_usec: event.time_usec(),
id: event.seat_slot(),
x_normed: Fixed::from_f64(event.x_transformed(1)),
y_normed: Fixed::from_f64(event.y_transformed(1)),
})
}

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

fn handle_touch_frame(self: &Rc<Self>, event: LibInputEvent) {
let (_, dev) = unpack!(self, event, touch_event);
dev.event(InputEvent::TouchFrame)
}
}
39 changes: 39 additions & 0 deletions src/cli/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ pub enum DeviceCommand {
MapToOutput(MapToOutputArgs),
/// Removes the mapping from this device to an output.
RemoveMapping,
/// Set the calibration matrix.
SetCalibrationMatrix(SetCalibrationMatrixArgs),
}

#[derive(ValueEnum, Debug, Clone)]
Expand Down Expand Up @@ -200,6 +202,16 @@ pub struct SetTransformMatrixArgs {
pub m22: f64,
}

#[derive(Args, Debug, Clone)]
pub struct SetCalibrationMatrixArgs {
pub m00: f32,
pub m01: f32,
pub m02: f32,
pub m10: f32,
pub m11: f32,
pub m12: f32,
}

#[derive(Args, Debug, Clone)]
pub struct MapToOutputArgs {
/// The output to map to.
Expand Down Expand Up @@ -272,6 +284,7 @@ struct InputDevice {
pub px_per_wheel_scroll: Option<f64>,
pub transform_matrix: Option<[[f64; 2]; 2]>,
pub output: Option<String>,
pub calibration_matrix: Option<[[f32; 3]; 2]>,
}

#[derive(Clone, Debug, Default)]
Expand Down Expand Up @@ -595,6 +608,21 @@ impl Input {
output: None,
});
}
DeviceCommand::SetCalibrationMatrix(a) => {
self.handle_error(input, |e| {
eprintln!("Could not modify the calibration matrix: {}", e);
});
tc.send(jay_input::SetCalibrationMatrix {
self_id: input,
id: args.device,
m00: a.m00,
m01: a.m01,
m02: a.m02,
m10: a.m10,
m11: a.m11,
m12: a.m12,
});
}
}
tc.round_trip().await;
}
Expand Down Expand Up @@ -728,6 +756,9 @@ impl Input {
if let Some(v) = &device.output {
println!("{prefix} mapped to output: {}", v);
}
if let Some(v) = &device.calibration_matrix {
println!("{prefix} calibration matrix: {:?}", v);
}
}

async fn get(self: &Rc<Self>, input: JayInputId) -> Data {
Expand Down Expand Up @@ -792,6 +823,7 @@ impl Input {
px_per_wheel_scroll: is_pointer.then_some(msg.px_per_wheel_scroll),
transform_matrix: uapi::pod_read(msg.transform_matrix).ok(),
output: None,
calibration_matrix: None,
});
});
jay_input::InputDeviceOutput::handle(tc, input, data.clone(), |data, msg| {
Expand All @@ -800,6 +832,13 @@ impl Input {
last.output = Some(msg.output.to_string());
}
});
jay_input::CalibrationMatrix::handle(tc, input, data.clone(), |data, msg| {
let mut data = data.borrow_mut();
if let Some(last) = data.input_device.last_mut() {
last.calibration_matrix =
Some([[msg.m00, msg.m01, msg.m02], [msg.m10, msg.m11, msg.m12]]);
}
});
tc.round_trip().await;
let x = data.borrow_mut().clone();
x
Expand Down
51 changes: 50 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, TouchMotion, TouchUp,
},
},
},
Expand Down Expand Up @@ -583,6 +584,54 @@ 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();
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
13 changes: 13 additions & 0 deletions src/config/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,16 @@ impl ConfigProxyHandler {
Ok(())
}

fn handle_set_calibration_matrix(
&self,
device: InputDevice,
matrix: [[f32; 3]; 2],
) -> Result<(), CphError> {
let dev = self.get_device_handler_data(device)?;
dev.device.set_calibration_matrix(matrix);
Ok(())
}

fn handle_get_workspace(&self, name: &str) {
let name = Rc::new(name.to_owned());
let ws = match self.workspaces_by_name.get(&name) {
Expand Down Expand Up @@ -1897,6 +1907,9 @@ impl ConfigProxyHandler {
ClientMessage::SetTearingMode { connector, mode } => self
.handle_set_tearing_mode(connector, mode)
.wrn("set_tearing_mode")?,
ClientMessage::SetCalibrationMatrix { device, matrix } => self
.handle_set_calibration_matrix(device, matrix)
.wrn("set_calibration_matrix")?,
}
Ok(())
}
Expand Down
Loading
Loading