From f9e4e069cbd2f13c8ad72994cab98df22d52a28c Mon Sep 17 00:00:00 2001 From: Ferdinand Schober Date: Fri, 16 Sep 2022 13:02:09 +0200 Subject: [PATCH] implement server side mouse grab --- src/bin/client.rs | 3 +- src/bin/server.rs | 152 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 133 insertions(+), 22 deletions(-) diff --git a/src/bin/client.rs b/src/bin/client.rs index 2ef78b6..297e3d9 100644 --- a/src/bin/client.rs +++ b/src/bin/client.rs @@ -1,5 +1,4 @@ -use std::io::{self, Write}; -use std::{f64::consts::PI, net::UdpSocket}; +use std::net::UdpSocket; use wayland_protocols_wlr::virtual_pointer::v1::client::{ zwlr_virtual_pointer_manager_v1::ZwlrVirtualPointerManagerV1 as VpManager, diff --git a/src/bin/server.rs b/src/bin/server.rs index 19fc696..b89a3f2 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -5,7 +5,13 @@ use std::{ os::unix::prelude::AsRawFd, }; -use wayland_protocols::xdg::shell::client::{xdg_surface, xdg_toplevel, xdg_wm_base}; +use wayland_protocols::{ + wp::{ + pointer_constraints::zv1::client::{zwp_locked_pointer_v1, zwp_pointer_constraints_v1}, + relative_pointer::zv1::client::{zwp_relative_pointer_manager_v1, zwp_relative_pointer_v1}, + }, + xdg::shell::client::{xdg_surface, xdg_toplevel, xdg_wm_base}, +}; use wayland_client::{ protocol::{ @@ -27,6 +33,10 @@ struct App { xdg_surface: Option, socket: UdpSocket, surface_coords: (f64, f64), + pointer_constraints: Option, + rel_pointer_manager: Option, + pointer_lock: Option, + rel_pointer: Option, } fn main() { @@ -51,8 +61,12 @@ fn main() { surface: None, xdg_surface: None, top_level: None, - socket: UdpSocket::bind("127.0.0.1:42070").expect("couldn't bind to address"), + socket: UdpSocket::bind("0.0.0.0:42070").expect("couldn't bind to address"), surface_coords: (0.0, 0.0), + pointer_constraints: None, + rel_pointer_manager: None, + pointer_lock: None, + rel_pointer: None, }; // use roundtrip to process this event synchronously @@ -79,10 +93,10 @@ fn draw(f: &mut File, (width, height): (u32, u32)) { let mut buf = BufWriter::new(f); for y in 0..height { for x in 0..width { - let color: u32 = if (x + y / 32 * 32) % 64 < 32 { - 0x0 + let color: u32 = if (x + y / 8 * 8) % 16 < 8 { + 0xFF8EC07C } else { - 0xFF000000 + 0xFFFbF1C7 }; buf.write_all(&color.to_ne_bytes()).unwrap(); } @@ -98,7 +112,7 @@ impl App { buf[0..4].copy_from_slice(&time_bytes); buf[4..12].copy_from_slice(&x_bytes); buf[12..20].copy_from_slice(&y_bytes); - self.socket.send_to(&buf, "127.0.0.1:42069").unwrap(); + self.socket.send_to(&buf, "192.168.178.114:42069").unwrap(); } } @@ -121,11 +135,10 @@ impl Dispatch for App { "wl_compositor" => { app.compositor = Some(registry.bind::(name, 4, qh, ())); - // get the vp manager } "wl_shm" => { let shm = registry.bind::(name, 1, qh, ()); - let (width, height) = (512, 512); + let (width, height) = (64, 64); let mut file = tempfile::tempfile().unwrap(); draw(&mut file, (width, height)); let pool = @@ -148,6 +161,26 @@ impl Dispatch for App { app.wm_base = Some(registry.bind::(name, 1, &qh, ())); } + "zwp_pointer_constraints_v1" => { + app.pointer_constraints = Some( + registry.bind::( + name, + 1, + &qh, + (), + ), + ); + } + "zwp_relative_pointer_manager_v1" => { + app.rel_pointer_manager = Some( + registry.bind::( + name, + 1, + &qh, + (), + ), + ); + } _ => {} } } @@ -301,11 +334,11 @@ impl Dispatch for App { impl Dispatch for App { fn event( app: &mut Self, - _: &wl_pointer::WlPointer, + pointer: &wl_pointer::WlPointer, event: ::Event, _: &(), _: &Connection, - _: &QueueHandle, + qh: &QueueHandle, ) { match event { wl_pointer::Event::Enter { @@ -315,15 +348,22 @@ impl Dispatch for App { surface_y, } => { app.surface_coords = (surface_x, surface_y); - } - wl_pointer::Event::Motion { - time, - surface_x, - surface_y, - } => { - let (last_x, last_y) = app.surface_coords; - app.send_motion_event(time, surface_x - last_x, surface_y - last_y); - app.surface_coords = (surface_x, surface_y); + if app.pointer_lock.is_none() { + app.pointer_lock = Some(app.pointer_constraints.as_ref().unwrap().lock_pointer( + &app.surface.as_ref().unwrap(), + pointer, + None, + zwp_pointer_constraints_v1::Lifetime::Persistent, + qh, + (), + )); + } + if app.rel_pointer.is_none() { + app.rel_pointer = Some(app.rel_pointer_manager + .as_ref() + .unwrap() + .get_relative_pointer(pointer, qh, ())); + } } _ => (), } @@ -342,8 +382,80 @@ impl Dispatch for App { if let wl_keyboard::Event::Key { key, .. } = event { if key == 1 { // ESC key - state.running = false; + if let Some(pointer_lock) = state.pointer_lock.as_ref() { + pointer_lock.destroy(); + state.pointer_lock = None; + } + if let Some(rel_pointer) = state.rel_pointer.as_ref() { + rel_pointer.destroy(); + state.rel_pointer = None; + } } } } } + +impl Dispatch for App { + fn event( + _: &mut Self, + _: &zwp_pointer_constraints_v1::ZwpPointerConstraintsV1, + _: ::Event, + _: &(), + _: &Connection, + _: &QueueHandle, + ) { + // + } +} + +impl Dispatch for App { + fn event( + _: &mut Self, + _: &zwp_locked_pointer_v1::ZwpLockedPointerV1, + event: ::Event, + _: &(), + _: &Connection, + _: &QueueHandle, + ) { + match event { + zwp_locked_pointer_v1::Event::Locked => {} + _ => {} + } + } +} + +impl Dispatch for App { + fn event( + _: &mut Self, + _: &zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1, + _: ::Event, + _: &(), + _: &Connection, + _: &QueueHandle, + ) { + // + } +} + +impl Dispatch for App { + fn event( + app: &mut Self, + _: &zwp_relative_pointer_v1::ZwpRelativePointerV1, + event: ::Event, + _: &(), + _: &Connection, + _: &QueueHandle, + ) { + if let zwp_relative_pointer_v1::Event::RelativeMotion { + utime_hi, + utime_lo, + dx: _, + dy: _, + dx_unaccel, + dy_unaccel, + } = event { + let time = ((utime_hi as u64) << 32 | utime_lo as u64) / 1000; + app.send_motion_event(time as u32, dx_unaccel, dy_unaccel); + } + } +}