use std::{os::unix::prelude::AsRawFd, io::{Write, BufWriter}}; use lan_mouse::{protocol::{self, DataRequest}, config::Config}; use wayland_protocols_wlr::virtual_pointer::v1::client::{ zwlr_virtual_pointer_manager_v1::ZwlrVirtualPointerManagerV1 as VpManager, zwlr_virtual_pointer_v1::ZwlrVirtualPointerV1 as Vp, }; use wayland_protocols_misc::zwp_virtual_keyboard_v1::client::{ zwp_virtual_keyboard_manager_v1::ZwpVirtualKeyboardManagerV1 as VkManager, zwp_virtual_keyboard_v1::ZwpVirtualKeyboardV1 as Vk, }; use wayland_client::{ protocol::{wl_registry, wl_seat, wl_keyboard}, Connection, Dispatch, EventQueue, QueueHandle, }; use tempfile; // App State, implements Dispatch event handlers struct App { vpm: Option, vkm: Option, seat: Option, } // Implement `Dispatch event handler // user-data = () impl Dispatch for App { fn event( app: &mut Self, registry: &wl_registry::WlRegistry, event: wl_registry::Event, _: &(), _: &Connection, qh: &QueueHandle, ) { // Match global event to get globals after requesting them in main if let wl_registry::Event::Global { name, interface, .. } = event { // println!("[{}] {} (v{})", name, interface, version); match &interface[..] { "wl_keyboard" => { registry.bind::(name, 1, qh, ()); } "wl_seat" => { app.seat = Some(registry.bind::(name, 1, qh, ())); } "zwlr_virtual_pointer_manager_v1" => { app.vpm = Some(registry.bind::(name, 1, qh, ())); } "zwp_virtual_keyboard_manager_v1" => { app.vkm = Some(registry.bind::(name, 1, qh, ())); } _ => {} } } } } // The main function of our program fn main() { let config = Config::new("config.toml").unwrap(); // establish connection via environment-provided configuration. let conn = Connection::connect_to_env().unwrap(); // Retrieve the wayland display object let display = conn.display(); // Create an event queue for our event processing let mut event_queue = conn.new_event_queue(); let qh = event_queue.handle(); // Create a wl_registry object by sending the wl_display.get_registry request let _registry = display.get_registry(&qh, ()); let mut app = App { vpm: None, vkm: None, seat: None, }; // use roundtrip to process this event synchronously event_queue.roundtrip(&mut app).unwrap(); let vpm = app.vpm.as_ref().unwrap(); let vkm = app.vkm.as_ref().unwrap(); let seat = app.seat.as_ref().unwrap(); let pointer: Vp = vpm.create_virtual_pointer(None, &qh, ()); let keyboard: Vk = vkm.create_virtual_keyboard(&seat, &qh, ()); let connection = protocol::Connection::new(config); let data = loop { match connection.receive_data(DataRequest::KeyMap) { Some(data) => { break data } None => {} } }; // TODO use shm_open let f = tempfile::tempfile().unwrap(); let mut buf = BufWriter::new(&f); buf.write_all(&data[..]).unwrap(); buf.flush().unwrap(); keyboard.keymap(1, f.as_raw_fd(), data.len() as u32); event_queue.roundtrip(&mut app).unwrap(); udp_loop(&connection, &pointer, &keyboard, event_queue).unwrap(); } /// main loop handling udp packets fn udp_loop(connection: &protocol::Connection, pointer: &Vp, keyboard: &Vk, q: EventQueue) -> std::io::Result<()> { loop { if let Some(event) = connection.receive_event() { match event { protocol::Event::Mouse { t, x, y } => { pointer.motion(t, x, y); pointer.frame(); } protocol::Event::Button { t, b, s } => { pointer.button(t, b, s); pointer.frame(); } protocol::Event::Axis { t, a, v } => { pointer.axis(t, a, v); pointer.frame(); } protocol::Event::Key { t, k, s } => { keyboard.key(t, k, u32::from(s)); pointer.frame(); }, protocol::Event::KeyModifier { mods_depressed, mods_latched, mods_locked, group } => { keyboard.modifiers(mods_depressed, mods_latched, mods_locked, group); }, } } q.flush().unwrap(); } } impl Dispatch for App { fn event( _: &mut Self, _: &VpManager, _: ::Event, _: &(), _: &Connection, _: &QueueHandle, ) { // nothing to do here since no events are defined for VpManager } } impl Dispatch for App { fn event( _: &mut Self, _: &Vp, _: ::Event, _: &(), _: &Connection, _: &QueueHandle, ) { // no events defined for vp either } } impl Dispatch for App { fn event( _: &mut Self, _: &wl_keyboard::WlKeyboard, _: ::Event, _: &(), _: &Connection, _: &QueueHandle, ) { // } } impl Dispatch for App { fn event( _: &mut Self, _: &VkManager, _: ::Event, _: &(), _: &Connection, _: &QueueHandle, ) { // } } impl Dispatch for App { fn event( _: &mut Self, _: &Vk, _: ::Event, _: &(), _: &Connection, _: &QueueHandle, ) { // } } impl Dispatch for App { fn event( _: &mut Self, _: &wl_seat::WlSeat, _: ::Event, _: &(), _: &Connection, _: &QueueHandle, ) { // } }