From 05ef34fbe6a7fd09fdec73c441fe524749123cf6 Mon Sep 17 00:00:00 2001 From: buffet Date: Fri, 25 Jan 2019 10:47:04 +0100 Subject: [PATCH] Basic input and output managers --- src/input/manager.rs | 41 +++++++++++++++++++++++++++++----- src/input/mod.rs | 7 ++++-- src/input/pointer.rs | 41 ++++++++++++++++++++++++++++++++++ src/main.rs | 51 ++++++++++++++++++++++++++++++++++++++++--- src/output/manager.rs | 42 +++++++++++++++++++++++++++++++++++ src/output/mod.rs | 3 +++ 6 files changed, 175 insertions(+), 10 deletions(-) create mode 100644 src/input/pointer.rs create mode 100644 src/output/manager.rs create mode 100644 src/output/mod.rs diff --git a/src/input/manager.rs b/src/input/manager.rs index 89f6efd..1b69455 100644 --- a/src/input/manager.rs +++ b/src/input/manager.rs @@ -1,17 +1,48 @@ -use crate::input::Keyboard; +use crate::{ + input::{Keyboard, Pointer}, + CompositorState, +}; + +use log::debug; use wlroots::{ compositor, - input::{self, keyboard}, + input::{self, keyboard, pointer}, + with_handles, }; pub fn manager() -> input::manager::Builder { - input::manager::Builder::default().keyboard_added(keyboard_added) + input::manager::Builder::default() + .keyboard_added(keyboard_added) + .pointer_added(pointer_added) } fn keyboard_added( - _compositor_handle: compositor::Handle, - _keyboard_handle: keyboard::Handle, + compositor_handle: compositor::Handle, + keyboard_handle: keyboard::Handle, ) -> Option> { + debug!("Keyboard added"); + + with_handles!([(compositor: {compositor_handle})] => { + let compositor_state: &mut CompositorState = compositor.data.downcast_mut().unwrap(); + compositor_state.keyboards.push(keyboard_handle); + }) + .unwrap(); Some(Box::new(Keyboard)) } + +fn pointer_added( + compositor_handle: compositor::Handle, + pointer_handle: pointer::Handle, +) -> Option> { + debug!("Pointer added"); + + with_handles!([(compositor: {compositor_handle}), (pointer: {pointer_handle})] => { + let compositor_state: &mut CompositorState = compositor.downcast(); + compositor_state.cursor_handle + .run(|cursor| cursor.attach_input_device(pointer.input_device())) + .unwrap(); + }) + .unwrap(); + Some(Box::new(Pointer)) +} diff --git a/src/input/mod.rs b/src/input/mod.rs index a261e73..37cd2ca 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -1,5 +1,8 @@ -mod manager; mod keyboard; +mod manager; +mod pointer; pub use self::manager::*; -pub use self::keyboard::*; + +use self::keyboard::*; +use self::pointer::*; diff --git a/src/input/pointer.rs b/src/input/pointer.rs new file mode 100644 index 0000000..2ef0347 --- /dev/null +++ b/src/input/pointer.rs @@ -0,0 +1,41 @@ +use crate::CompositorState; + +use wlroots::{compositor, input::pointer, with_handles}; + +pub struct Pointer; + +impl pointer::Handler for Pointer { + fn on_motion_absolute( + &mut self, + compositor_handle: compositor::Handle, + _pointer_handle: pointer::Handle, + absolute_motion_event: &pointer::event::AbsoluteMotion, + ) { + with_handles!([(compositor: {compositor_handle})] => { + let compositor_state: &mut CompositorState = compositor.downcast(); + let (x, y) = absolute_motion_event.pos(); + + compositor_state.cursor_handle + .run(|cursor| cursor.warp_absolute(absolute_motion_event.device(), x, y)) + .unwrap(); + }) + .unwrap(); + } + + fn on_motion( + &mut self, + compositor_handle: compositor::Handle, + _pointer_handle: pointer::Handle, + motion_event: &pointer::event::Motion, + ) { + with_handles!([(compositor: {compositor_handle})] => { + let compositor_state: &mut CompositorState = compositor.downcast(); + let (dx, dy) = motion_event.delta(); + + compositor_state.cursor_handle + .run(|cursor| cursor.move_to(None, dx, dy)) + .unwrap(); + }) + .unwrap(); + } +} diff --git a/src/main.rs b/src/main.rs index a23f924..cfd298d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,53 @@ mod input; mod logger; +mod output; -use log::LevelFilter; +use log::{warn, LevelFilter}; -use wlroots::compositor; +use wlroots::{ + compositor, + cursor::{self, xcursor, Cursor}, + input::keyboard, + output::layout, +}; + +struct ExCursor; +impl cursor::Handler for ExCursor {} + +struct ExOutputLayout; +impl layout::Handler for ExOutputLayout {} + +struct CompositorState { + pub xcursor_manager: xcursor::Manager, + pub cursor_handle: cursor::Handle, + pub layout_handle: layout::Handle, + pub keyboards: Vec, +} + +impl CompositorState { + pub fn new() -> Self { + let mut xcursor_manager = xcursor::Manager::create(String::from("default"), 24) + .expect("Could not create xcursor manager"); + + if xcursor_manager.load(1.0) { + warn!("Cursor did not load"); + } + + let cursor_handle = Cursor::create(Box::new(ExCursor)); + cursor_handle + .run(|c| xcursor_manager.set_cursor_image(String::from("left_ptr"), c)) + .unwrap(); + + let layout_handle = layout::Layout::create(Box::new(ExOutputLayout)); + + CompositorState { + xcursor_manager: xcursor_manager, + cursor_handle: cursor_handle, + layout_handle: layout_handle, + keyboards: Vec::new(), + } + } +} fn main() { logger::init(LevelFilter::Info); @@ -16,5 +60,6 @@ fn build_compositor() -> compositor::Compositor { .gles2(true) .data_device(true) .input_manager(input::manager()) - .build_auto(()) + .output_manager(output::manager()) + .build_auto(CompositorState::new()) } diff --git a/src/output/manager.rs b/src/output/manager.rs new file mode 100644 index 0000000..c9cb0e9 --- /dev/null +++ b/src/output/manager.rs @@ -0,0 +1,42 @@ +use crate::CompositorState; + +use log::debug; +use wlroots::{compositor, output, with_handles}; + +pub fn manager() -> output::manager::Builder { + output::manager::Builder::default().output_added(output_added) +} + +struct Output; + +impl output::Handler for Output {} + +fn output_added<'output>( + compositor_handle: compositor::Handle, + output_builder: output::Builder<'output>, +) -> Option> { + debug!("Output added"); + + let mut result = output_builder.build_best_mode(Output); + with_handles!([(compositor: {compositor_handle})] => { + let compositor_state: &mut CompositorState = compositor.data.downcast_mut().unwrap(); + let layout_handle = &mut compositor_state.layout_handle; + let cursor_handle = &mut compositor_state.cursor_handle; + let xcursor_manager = &mut compositor_state.xcursor_manager; + // TODO use output config if present instead of auto + with_handles!([ + (layout: {layout_handle}), + (cursor: {cursor_handle}), + (output: {&mut result.output}) + ] => { + layout.add_auto(output); + cursor.attach_output_layout(layout); + xcursor_manager.load(output.scale()); + xcursor_manager.set_cursor_image("left_ptr".to_string(), cursor); + let (x, y) = cursor.coords(); + cursor.warp(None, x, y); + }).unwrap(); + Some(result) + }) + .unwrap() +} diff --git a/src/output/mod.rs b/src/output/mod.rs new file mode 100644 index 0000000..c9d7a66 --- /dev/null +++ b/src/output/mod.rs @@ -0,0 +1,3 @@ +mod manager; + +pub use self::manager::*;