unfettered-keyboard/src/wayland/seat.rs
2024-08-05 18:26:35 -04:00

198 lines
4.8 KiB
Rust

// 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<D: Display, K: Keyboard, T> {
seat: wl_seat::WlSeat,
queue: QueueHandle<T>,
ptr: Option<wl_pointer::WlPointer>,
touch: Option<WlTouch>,
button: Button<D, K>,
x_scale: f64,
y_scale: f64,
mouse_x: f64,
mouse_y: f64,
actions: Vec<TouchAction>,
}
impl<D: Display, K: Keyboard,
T: Dispatch<wl_pointer::WlPointer, ()>
+ Dispatch<WlTouch, ()>
+ 'static> Seat<D, K, T> {
pub fn new(layout: Layout, kbd: K, gfx: Arc<Mutex<Graphics<D>>>,
queue: QueueHandle<T>, seat: wl_seat::WlSeat) -> Seat<D, K, T>
{
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<D, K>
{
&self.button
}
#[inline(always)]
pub fn button_mut(&mut self) -> &mut Button<D, K>
{
&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();
}
}