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 Apr 29, 2024
1 parent a20008d commit 68ed82a
Show file tree
Hide file tree
Showing 30 changed files with 888 additions and 49 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 @@ -170,7 +170,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 @@ -181,6 +180,5 @@ 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.
- Tablet support.
- Tearing updates of fullscreen games.
4 changes: 4 additions & 0 deletions jay-config/src/_private/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,10 @@ impl Client {
self.send(&ClientMessage::SetTransformMatrix { device, matrix })
}

pub fn set_mapped_output(&self, device: InputDevice, connector: (ConnectorType, u32)) {
self.send(&ClientMessage::SetMappedOutput { device, connector })
}

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 @@ -229,6 +229,10 @@ pub enum ClientMessage<'a> {
device: InputDevice,
matrix: [[f64; 2]; 2],
},
SetMappedOutput {
device: InputDevice,
connector: (ConnectorType, u32),
},
GetDeviceName {
device: InputDevice,
},
Expand Down
9 changes: 8 additions & 1 deletion jay-config/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use {
keyboard::{mods::Modifiers, Keymap},
Axis, Direction, ModifiedKeySym, Workspace,
_private::{ipc::WorkspaceSource, DEFAULT_SEAT_NAME},
video::Connector,
video::{connector_type::ConnectorType, Connector},
},
serde::{Deserialize, Serialize},
std::time::Duration,
Expand Down Expand Up @@ -80,6 +80,13 @@ impl InputDevice {
get!().set_transform_matrix(self, matrix);
}

/// Sets the output to which input from this device is mapped to.
///
/// This only applies to touch devices.
pub fn set_mapped_output(self, connector: (ConnectorType, u32)) {
get!().set_mapped_output(self, connector);
}

/// Returns the name of the device.
pub fn name(self) -> String {
get!(String::new()).device_name(self)
Expand Down
34 changes: 34 additions & 0 deletions src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,13 @@ pub enum ConnectorEvent {
Available,
}

#[derive(Copy, Clone, Debug)]
pub struct MappedOutput {
pub ty: ConnectorType,
pub idx: u32,
pub conn_id: Option<ConnectorId>,
}

pub trait HardwareCursor: Debug {
fn set_enabled(&self, enabled: bool);
fn get_buffer(&self) -> Rc<dyn GfxFramebuffer>;
Expand Down Expand Up @@ -145,6 +152,10 @@ pub trait InputDevice {
None
}
fn set_transform_matrix(&self, matrix: TransformMatrix);
fn mapped_output(&self) -> Option<MappedOutput> {
None
}
fn set_mapped_output(&self, output: MappedOutput);
fn name(&self) -> Rc<String>;
fn dev_t(&self) -> Option<c::dev_t> {
None
Expand Down Expand Up @@ -212,6 +223,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 @@ -253,6 +281,12 @@ pub enum InputEvent {
state: KeyState,
},

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

AxisPx {
dist: Fixed,
axis: ScrollAxis,
Expand Down
13 changes: 12 additions & 1 deletion src/backends/metal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use {
async_engine::SpawnedFuture,
backend::{
Backend, InputDevice, InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId,
InputEvent, KeyState, TransformMatrix,
InputEvent, KeyState, MappedOutput, TransformMatrix,
},
backends::metal::video::{MetalDrmDeviceData, MetalRenderContext, PendingDrmDevice},
dbus::{DbusError, SignalHandler},
Expand Down Expand Up @@ -298,6 +298,7 @@ struct MetalInputDevice {
cb: CloneCell<Option<Rc<dyn Fn()>>>,
name: CloneCell<Rc<String>>,
transform_matrix: Cell<Option<TransformMatrix>>,
mapped_output: Cell<Option<MappedOutput>>,

// state
pressed_keys: SmallMap<u32, (), 5>,
Expand Down Expand Up @@ -504,6 +505,12 @@ impl InputDevice for MetalInputDevice {
self.transform_matrix.set(Some(matrix));
}

fn set_mapped_output(&self, output: MappedOutput) {
if self.has_capability(InputDeviceCapability::Touch) {
self.mapped_output.set(Some(output));
}
}

fn name(&self) -> Rc<String> {
self.name.get()
}
Expand Down Expand Up @@ -597,6 +604,10 @@ impl InputDevice for MetalInputDevice {
fn natural_scrolling_enabled(&self) -> Option<bool> {
self.effective.natural_scrolling_enabled.get()
}

fn mapped_output(&self) -> Option<MappedOutput> {
self.mapped_output.get()
}
}

impl MetalInputDevice {
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,
libinput::{
Expand Down Expand Up @@ -103,6 +103,11 @@ impl MetalBackend {
c::LIBINPUT_EVENT_GESTURE_HOLD_BEGIN => self.handle_gesture_hold_begin(event),
c::LIBINPUT_EVENT_GESTURE_HOLD_END => self.handle_gesture_hold_end(event),
c::LIBINPUT_EVENT_SWITCH_TOGGLE => self.handle_switch_toggle(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 @@ -320,4 +325,61 @@ impl MetalBackend {
event: switch_event,
});
}

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,
})
}
}
1 change: 1 addition & 0 deletions src/backends/metal/monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ impl MetalBackend {
pressed_buttons: Default::default(),
desired: Default::default(),
transform_matrix: Default::default(),
mapped_output: Default::default(),
effective: Default::default(),
});
slots[slot] = Some(dev.clone());
Expand Down
10 changes: 9 additions & 1 deletion src/backends/x.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use {
AxisSource, Backend, BackendDrmDevice, BackendEvent, Connector, ConnectorEvent,
ConnectorId, ConnectorKernelId, DrmDeviceId, DrmEvent, InputDevice,
InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId, InputEvent, KeyState,
Mode, MonitorInfo, ScrollAxis, TransformMatrix, AXIS_120,
MappedOutput, Mode, MonitorInfo, ScrollAxis, TransformMatrix, AXIS_120,
},
fixed::Fixed,
format::XRGB8888,
Expand Down Expand Up @@ -1203,6 +1203,10 @@ impl InputDevice for XSeatKeyboard {
fn set_natural_scrolling_enabled(&self, enabled: bool) {
let _ = enabled;
}

fn set_mapped_output(&self, output: MappedOutput) {
let _ = output;
}
}

impl InputDevice for XSeatMouse {
Expand Down Expand Up @@ -1272,4 +1276,8 @@ impl InputDevice for XSeatMouse {
fn set_natural_scrolling_enabled(&self, enabled: bool) {
let _ = enabled;
}

fn set_mapped_output(&self, output: MappedOutput) {
let _ = output;
}
}
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
22 changes: 20 additions & 2 deletions src/config/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use {
async_engine::SpawnedFuture,
backend::{
self, ConnectorId, DrmDeviceId, InputDeviceAccelProfile, InputDeviceCapability,
InputDeviceId,
InputDeviceId, MappedOutput,
},
compositor::MAX_EXTENTS,
config::ConfigProxy,
Expand Down Expand Up @@ -47,7 +47,7 @@ use {
logging::LogLevel,
theme::{colors::Colorable, sized::Resizable},
timer::Timer as JayTimer,
video::{Connector, DrmDevice, GfxApi, Transform},
video::{connector_type::ConnectorType, Connector, DrmDevice, GfxApi, Transform},
Axis, Direction, Workspace,
},
libloading::Library,
Expand Down Expand Up @@ -658,6 +658,21 @@ impl ConfigProxyHandler {
Ok(())
}

fn handle_set_mapped_output(
&self,
device: InputDevice,
connector: (ConnectorType, u32),
) -> Result<(), CphError> {
let dev = self.get_device_handler_data(device)?;
let ty = crate::video::drm::ConnectorType::from_config(connector.0);
dev.device.set_mapped_output(MappedOutput {
ty,
idx: connector.1,
conn_id: None,
});
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 @@ -1579,6 +1594,9 @@ impl ConfigProxyHandler {
ClientMessage::SetTransformMatrix { device, matrix } => self
.handle_set_transform_matrix(device, matrix)
.wrn("set_transform_matrix")?,
ClientMessage::SetMappedOutput { device, connector } => self
.handle_set_mapped_output(device, connector)
.wrn("set_mapped_output")?,
ClientMessage::GetDeviceName { device } => {
self.handle_get_device_name(device).wrn("get_device_name")?
}
Expand Down
Loading

0 comments on commit 68ed82a

Please sign in to comment.