feat: wayland
This commit is contained in:
191
src/wayland/core/seat.rs
Normal file
191
src/wayland/core/seat.rs
Normal file
@@ -0,0 +1,191 @@
|
||||
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(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user