192 lines
4.4 KiB
Rust
192 lines
4.4 KiB
Rust
use crate::wayland::core::{keyboard::Keyboard, pointer::Pointer, surface::Surface, touch::Touch};
|
|
use mint::Vector2;
|
|
use std::sync::Arc;
|
|
use std::sync::OnceLock;
|
|
pub use waynest::server::protocol::core::wayland::wl_seat::*;
|
|
use waynest::server::{Client, Dispatcher, Result};
|
|
use waynest::wire::{Fixed, ObjectId};
|
|
|
|
#[derive(Debug)]
|
|
pub enum SeatMessage {
|
|
PointerMotion {
|
|
surface: Arc<Surface>,
|
|
position: Vector2<f32>,
|
|
},
|
|
PointerButton {
|
|
surface: Arc<Surface>,
|
|
button: u32,
|
|
pressed: bool,
|
|
},
|
|
PointerScroll {
|
|
surface: Arc<Surface>,
|
|
scroll_distance: Option<Vector2<f32>>,
|
|
scroll_steps: Option<Vector2<f32>>,
|
|
},
|
|
KeyboardKey {
|
|
surface: Arc<Surface>,
|
|
keymap_id: u64,
|
|
key: u32,
|
|
pressed: bool,
|
|
},
|
|
TouchDown {
|
|
surface: Arc<Surface>,
|
|
id: u32,
|
|
position: Vector2<f32>,
|
|
},
|
|
TouchMove {
|
|
id: u32,
|
|
position: Vector2<f32>,
|
|
},
|
|
TouchUp {
|
|
id: u32,
|
|
},
|
|
Reset,
|
|
}
|
|
|
|
pub fn fixed_from_f32(f: f32) -> Fixed {
|
|
unsafe { Fixed::from_raw((f * 256.0).round() as u32) }
|
|
}
|
|
|
|
#[derive(Default, Dispatcher)]
|
|
pub struct Seat {
|
|
pointer: OnceLock<Arc<Pointer>>,
|
|
keyboard: OnceLock<Arc<Keyboard>>,
|
|
touch: OnceLock<Arc<Touch>>,
|
|
}
|
|
|
|
impl Seat {
|
|
pub fn new() -> Self {
|
|
Self::default()
|
|
}
|
|
|
|
pub async fn advertise_capabilities(&self, client: &mut Client, id: ObjectId) -> Result<()> {
|
|
tracing::debug!("Advertising seat capabilities with id {}", id);
|
|
let capabilities = Capability::Pointer | Capability::Keyboard | Capability::Touch;
|
|
WlSeat::capabilities(self, client, id, capabilities).await?;
|
|
tracing::debug!("Capabilities advertised: {:?}", capabilities);
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn handle_message(&self, client: &mut Client, message: SeatMessage) -> Result<()> {
|
|
match message {
|
|
SeatMessage::PointerMotion { surface, position } => {
|
|
if let Some(pointer) = self.pointer.get() {
|
|
pointer
|
|
.handle_pointer_motion(client, surface, position)
|
|
.await?;
|
|
}
|
|
}
|
|
SeatMessage::PointerButton {
|
|
surface,
|
|
button,
|
|
pressed,
|
|
} => {
|
|
if let Some(pointer) = self.pointer.get() {
|
|
pointer
|
|
.handle_pointer_button(client, surface, button, pressed)
|
|
.await?;
|
|
}
|
|
}
|
|
SeatMessage::PointerScroll {
|
|
surface,
|
|
scroll_distance,
|
|
scroll_steps,
|
|
} => {
|
|
if let Some(pointer) = self.pointer.get() {
|
|
pointer
|
|
.handle_pointer_scroll(client, surface, scroll_distance, scroll_steps)
|
|
.await?;
|
|
}
|
|
}
|
|
SeatMessage::KeyboardKey {
|
|
surface,
|
|
keymap_id,
|
|
key,
|
|
pressed,
|
|
} => {
|
|
if let Some(keyboard) = self.keyboard.get() {
|
|
keyboard
|
|
.handle_keyboard_key(client, surface, keymap_id, key - 8, pressed)
|
|
.await?;
|
|
}
|
|
}
|
|
SeatMessage::TouchDown {
|
|
surface,
|
|
id,
|
|
position,
|
|
} => {
|
|
if let Some(touch) = self.touch.get() {
|
|
touch
|
|
.handle_touch_down(client, surface, id, position)
|
|
.await?;
|
|
}
|
|
}
|
|
SeatMessage::TouchMove { id, position } => {
|
|
if let Some(touch) = self.touch.get() {
|
|
touch.handle_touch_move(client, id, position).await?;
|
|
}
|
|
}
|
|
SeatMessage::TouchUp { id } => {
|
|
if let Some(touch) = self.touch.get() {
|
|
touch.handle_touch_up(client, id).await?;
|
|
}
|
|
}
|
|
SeatMessage::Reset => {
|
|
if let Some(pointer) = self.pointer.get() {
|
|
pointer.reset(client).await?;
|
|
}
|
|
if let Some(keyboard) = self.keyboard.get() {
|
|
keyboard.reset(client).await?;
|
|
}
|
|
if let Some(touch) = self.touch.get() {
|
|
touch.reset(client).await?;
|
|
}
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
impl WlSeat for Seat {
|
|
/// https://wayland.app/protocols/wayland#wl_seat:request:get_pointer
|
|
async fn get_pointer(
|
|
&self,
|
|
client: &mut Client,
|
|
_sender_id: ObjectId,
|
|
id: ObjectId,
|
|
) -> Result<()> {
|
|
let pointer = client.insert(id, Pointer::new(id));
|
|
let _ = self.pointer.set(pointer);
|
|
Ok(())
|
|
}
|
|
|
|
/// https://wayland.app/protocols/wayland#wl_seat:request:get_keyboard
|
|
async fn get_keyboard(
|
|
&self,
|
|
client: &mut Client,
|
|
_sender_id: ObjectId,
|
|
id: ObjectId,
|
|
) -> Result<()> {
|
|
tracing::info!("Getting keyboard");
|
|
let keyboard = client.insert(id, Keyboard::new(id));
|
|
let _ = self.keyboard.set(keyboard);
|
|
Ok(())
|
|
}
|
|
|
|
/// https://wayland.app/protocols/wayland#wl_seat:request:get_touch
|
|
async fn get_touch(
|
|
&self,
|
|
client: &mut Client,
|
|
_sender_id: ObjectId,
|
|
id: ObjectId,
|
|
) -> Result<()> {
|
|
let touch = client.insert(id, Touch(id));
|
|
let _ = self.touch.set(touch);
|
|
Ok(())
|
|
}
|
|
|
|
/// https://wayland.app/protocols/wayland#wl_seat:request:release
|
|
async fn release(&self, _client: &mut Client, _sender_id: ObjectId) -> Result<()> {
|
|
Ok(())
|
|
}
|
|
}
|