// SPDX-License-Identifier: GPL-3.0-only /* * Copyright (c) 2024, Richard Acayan. All rights reserved. */ use crate::core::Button; use crate::core::Display; use crate::core::Graphics; use crate::core::Keyboard; use crate::core::Layout; use crate::core::ModState; use std::sync::Arc; use std::sync::Mutex; use wayland_client::protocol::wl_pointer; use wayland_client::protocol::wl_seat; use wayland_client::protocol::wl_touch::WlTouch; use wayland_client::Dispatch; use wayland_client::QueueHandle; enum PressAction { Pos(f64, f64), Press(f64, f64), Release, } struct TouchAction { id: usize, act: PressAction, } pub struct Seat { seat: wl_seat::WlSeat, queue: QueueHandle, ptr: Option, touch: Option, button: Button, x_scale: f64, y_scale: f64, mouse_x: f64, mouse_y: f64, actions: Vec, } impl + Dispatch + 'static> Seat { pub fn new(layout: Layout, kbd: K, gfx: Arc>>, queue: QueueHandle, seat: wl_seat::WlSeat) -> Seat { let actions = Vec::new(); let button = Button::new(layout, kbd, gfx); Seat { seat, queue, ptr: None, touch: None, button, x_scale: 0.0, y_scale: 0.0, mouse_x: 0.0, mouse_y: 0.0, actions, } } #[inline(always)] pub fn button(&self) -> &Button { &self.button } #[inline(always)] pub fn button_mut(&mut self) -> &mut Button { &mut self.button } #[inline(always)] pub fn layout(&self) -> &Layout { self.button.layout() } #[inline(always)] pub fn keyboard(&self) -> &K { self.button.keyboard() } #[inline(always)] pub fn keyboard_mut(&mut self) -> &mut K { self.button.keyboard_mut() } #[inline(always)] pub fn mod_state(&self) -> &[ModState] { self.button.mod_state() } pub fn set_capabilities(&mut self, caps: wl_seat::Capability) { if caps.contains(wl_seat::Capability::Pointer) { self.ptr = Some(self.seat.get_pointer(&self.queue, ())); } if caps.contains(wl_seat::Capability::Touch) { self.touch = Some(self.seat.get_touch(&self.queue, ())); } } pub fn set_scale(&mut self, x_scale: f64, y_scale: f64) { self.x_scale = x_scale; self.y_scale = y_scale; } pub fn ptr_motion(&mut self, x: f64, y: f64) { let (x, y) = (x * self.x_scale, y * self.y_scale); self.mouse_x = x; self.mouse_y = y; let act = TouchAction { id: 0, act: PressAction::Pos(x, y), }; self.actions.push(act); } pub fn ptr_button(&mut self, state: wl_pointer::ButtonState) { match state { wl_pointer::ButtonState::Pressed => { let (x, y) = (self.mouse_x, self.mouse_y); let act = TouchAction { id: 0, act: PressAction::Press(x, y), }; self.actions.push(act); }, wl_pointer::ButtonState::Released => { let act = TouchAction { id: 0, act: PressAction::Release, }; self.actions.push(act); }, _ => eprintln!("warn: ignoring unknown pointer event"), } } pub fn touch_press(&mut self, id: u32, x: f64, y: f64) { let id = id as usize + 1; let (x, y) = (x * self.x_scale, y * self.y_scale); let act = TouchAction { id, act: PressAction::Press(x, y), }; self.actions.push(act); } pub fn touch_pos(&mut self, id: u32, x: f64, y: f64) { let id = id as usize + 1; let (x, y) = (x * self.x_scale, y * self.y_scale); let act = TouchAction { id, act: PressAction::Pos(x, y), }; self.actions.push(act); } pub fn touch_release(&mut self, id: u32) { let id = id as usize + 1; let act = TouchAction { id, act: PressAction::Release, }; self.actions.push(act); } pub fn commit(&mut self) { for action in &self.actions { match action.act { PressAction::Press(x, y) => { self.button.press(action.id, x, y); }, PressAction::Pos(x, y) => { self.button.pos(action.id, x, y); }, PressAction::Release => { self.button.release(action.id); }, } } // Reset the action for the next frame. self.actions.clear(); } }