diff --git a/examples/drm.rs b/examples/drm.rs index 077af24..5db2ada 100644 --- a/examples/drm.rs +++ b/examples/drm.rs @@ -34,7 +34,6 @@ use std::os::unix::io::AsRawFd; use std::os::unix::io::RawFd; use std::rc::Rc; use std::time::Duration; -use wayland_server::EventLoopHandle; #[derive(Debug)] pub struct Card(File); @@ -56,7 +55,7 @@ fn main() { ); // Initialize the wayland server - let (mut display, mut event_loop) = wayland_server::create_display(); + let (mut display, mut event_loop) = wayland_server::Display::new(); /* * Initialize the drm backend @@ -124,10 +123,10 @@ fn main() { * Initialize the globals */ - init_shm_global(&mut event_loop, vec![], log.clone()); + init_shm_global(&mut display, event_loop.token(), vec![], log.clone()); let (compositor_token, _shell_state_token, window_map) = - init_shell(&mut event_loop, log.clone(), egl_display.clone()); + init_shell(&mut display, event_loop.token(), log.clone(), egl_display); /* * Add a listening socket: @@ -139,7 +138,7 @@ fn main() { * Register the DrmDevice on the EventLoop */ let _source = drm_device_bind( - &mut event_loop, + &event_loop.token(), device, DrmHandlerImpl { compositor_token, @@ -159,7 +158,7 @@ fn main() { } pub struct DrmHandlerImpl { - compositor_token: CompositorToken>>>, + compositor_token: CompositorToken, window_map: Rc>, drawer: GliumDrawer>, logger: ::slog::Logger, @@ -167,8 +166,11 @@ pub struct DrmHandlerImpl { impl DrmHandler for DrmHandlerImpl { fn ready( - &mut self, _evlh: &mut EventLoopHandle, _device: &mut DrmDevice, _crtc: crtc::Handle, - _frame: u32, _duration: Duration, + &mut self, + _device: &mut DrmDevice, + _crtc: crtc::Handle, + _frame: u32, + _duration: Duration, ) { let mut frame = self.drawer.draw(); frame.clear_color(0.8, 0.8, 0.9, 1.0); @@ -215,8 +217,8 @@ impl DrmHandler for DrmHandlerImpl { if let Some(ref texture) = attributes.user_data.texture { if let Ok(subdata) = Role::::data(role) { - x += subdata.x; - y += subdata.y; + x += subdata.location.0; + y += subdata.location.1; } info!(self.logger, "Render window"); self.drawer.render_texture( @@ -248,7 +250,7 @@ impl DrmHandler for DrmHandlerImpl { frame.finish().unwrap(); } - fn error(&mut self, _evlh: &mut EventLoopHandle, _device: &mut DrmDevice, error: DrmError) { + fn error(&mut self, _device: &mut DrmDevice, error: DrmError) { panic!("{:?}", error); } } diff --git a/examples/helpers/glium.rs b/examples/helpers/glium.rs index 46b1087..ecb2ec2 100644 --- a/examples/helpers/glium.rs +++ b/examples/helpers/glium.rs @@ -135,8 +135,13 @@ impl GliumDrawer { } pub fn render_texture( - &self, target: &mut glium::Frame, texture: &Texture2d, y_inverted: bool, - surface_dimensions: (u32, u32), surface_location: (i32, i32), screen_size: (u32, u32), + &self, + target: &mut glium::Frame, + texture: &Texture2d, + y_inverted: bool, + surface_dimensions: (u32, u32), + surface_location: (i32, i32), + screen_size: (u32, u32), blending: glium::Blend, ) { let xscale = 2.0 * (surface_dimensions.0 as f32) / (screen_size.0 as f32); diff --git a/examples/helpers/implementations.rs b/examples/helpers/implementations.rs index a8664ae..2714773 100644 --- a/examples/helpers/implementations.rs +++ b/examples/helpers/implementations.rs @@ -3,14 +3,15 @@ use glium::texture::Texture2d; use rand; use smithay::backend::graphics::egl::wayland::{BufferAccessError, Format}; use smithay::backend::graphics::egl::wayland::{EGLDisplay, EGLImages}; -use smithay::wayland::compositor::{compositor_init, CompositorToken, SurfaceAttributes, - SurfaceUserImplementation}; -use smithay::wayland::shell::{shell_init, PopupConfigure, ShellState, ShellSurfaceRole, - ShellSurfaceUserImplementation, ToplevelConfigure}; +use smithay::wayland::compositor::{compositor_init, CompositorToken, SurfaceAttributes, SurfaceEvent}; +use smithay::wayland::shell::xdg::{xdg_shell_init, PopupConfigure, ShellEvent, ShellState, ShellSurfaceRole, + ToplevelConfigure}; use smithay::wayland::shm::with_buffer_contents as shm_buffer_contents; use std::cell::RefCell; use std::rc::Rc; -use wayland_server::{EventLoop, StateToken}; +use std::sync::{Arc, Mutex}; +use wayland_server::{Display, LoopToken, Resource}; +use wayland_server::protocol::{wl_buffer, wl_callback, wl_surface}; define_roles!(Roles => [ ShellSurface, ShellSurfaceRole ] ); @@ -25,110 +26,62 @@ pub enum Buffer { Shm { data: Vec, size: (u32, u32) }, } -pub fn surface_implementation( -) -> SurfaceUserImplementation>>> { - SurfaceUserImplementation { - commit: |_, display, surface, token| { - // we retrieve the contents of the associated buffer and copy it - token.with_surface_data(surface, |attributes| { - match attributes.buffer.take() { - Some(Some((buffer, (_x, _y)))) => { - // we ignore hotspot coordinates in this simple example - match if let Some(display) = display.borrow().as_ref() { - display.egl_buffer_contents(buffer) - } else { - Err(BufferAccessError::NotManaged(buffer)) - } { - Ok(images) => { - match images.format { - Format::RGB => {} - Format::RGBA => {} - _ => { - // we don't handle the more complex formats here. - attributes.user_data.buffer = None; - attributes.user_data.texture = None; - return; - } - }; +fn surface_commit( + surface: &Resource, + token: CompositorToken, + display: &RefCell>, +) { + // we retrieve the contents of the associated buffer and copy it + token.with_surface_data(surface, |attributes| { + match attributes.buffer.take() { + Some(Some((buffer, (_x, _y)))) => { + // we ignore hotspot coordinates in this simple example + match if let Some(display) = display.borrow().as_ref() { + display.egl_buffer_contents(buffer) + } else { + Err(BufferAccessError::NotManaged(buffer)) + } { + Ok(images) => { + match images.format { + Format::RGB => {} + Format::RGBA => {} + _ => { + // we don't handle the more complex formats here. + attributes.user_data.buffer = None; attributes.user_data.texture = None; - attributes.user_data.buffer = Some(Buffer::Egl { images }); + return; } - Err(BufferAccessError::NotManaged(buffer)) => { - shm_buffer_contents(&buffer, |slice, data| { - let offset = data.offset as usize; - let stride = data.stride as usize; - let width = data.width as usize; - let height = data.height as usize; - let mut new_vec = Vec::with_capacity(width * height * 4); - for i in 0..height { - new_vec - .extend(&slice[(offset + i * stride)..(offset + i * stride + width * 4)]); - } - attributes.user_data.texture = None; - attributes.user_data.buffer = Some(Buffer::Shm { data: new_vec, size: (data.width as u32, data.height as u32) }); - }).expect("Got EGL buffer with no set EGLDisplay. You need to unbind your EGLContexts before dropping them!"); - buffer.release(); - } - Err(err) => panic!("EGL error: {}", err), - } - } - Some(None) => { - // erase the contents - attributes.user_data.buffer = None; + }; attributes.user_data.texture = None; + attributes.user_data.buffer = Some(Buffer::Egl { images }); } - None => {} + Err(BufferAccessError::NotManaged(buffer)) => { + shm_buffer_contents(&buffer, |slice, data| { + let offset = data.offset as usize; + let stride = data.stride as usize; + let width = data.width as usize; + let height = data.height as usize; + let mut new_vec = Vec::with_capacity(width * height * 4); + for i in 0..height { + new_vec + .extend(&slice[(offset + i * stride)..(offset + i * stride + width * 4)]); + } + attributes.user_data.texture = None; + attributes.user_data.buffer = Some(Buffer::Shm { data: new_vec, size: (data.width as u32, data.height as u32) }); + }).expect("Got EGL buffer with no set EGLDisplay. You need to unbind your EGLContexts before dropping them!"); + buffer.send(wl_buffer::Event::Release); + } + Err(err) => panic!("EGL error: {}", err), } - }); - }, - frame: |_, _, _, callback, _| { - callback.done(0); - }, - } -} - -pub struct ShellIData { - pub token: CompositorToken>>>, - pub window_map: Rc>>, (), F>>>, -} - -pub fn shell_implementation( -) -> ShellSurfaceUserImplementation>>, ShellIData, ()> -where - F: Fn(&SurfaceAttributes) -> Option<(i32, i32)>, -{ - ShellSurfaceUserImplementation { - new_client: |_, _, _| {}, - client_pong: |_, _, _| {}, - new_toplevel: |_, idata, toplevel| { - // place the window at a random location in the [0;300]x[0;300] square - use rand::distributions::{IndependentSample, Range}; - let range = Range::new(0, 300); - let mut rng = rand::thread_rng(); - let x = range.ind_sample(&mut rng); - let y = range.ind_sample(&mut rng); - idata.window_map.borrow_mut().insert(toplevel, (x, y)); - ToplevelConfigure { - size: None, - states: vec![], - serial: 42, } - }, - new_popup: |_, _, _| PopupConfigure { - size: (10, 10), - position: (10, 10), - serial: 42, - }, - move_: |_, _, _, _, _| {}, - resize: |_, _, _, _, _, _| {}, - grab: |_, _, _, _, _| {}, - change_display_state: |_, _, _, _, _, _, _| ToplevelConfigure { - size: None, - states: vec![], - serial: 42, - }, - show_window_menu: |_, _, _, _, _, _, _| {}, - } + Some(None) => { + // erase the contents + attributes.user_data.buffer = None; + attributes.user_data.texture = None; + } + None => {} + } + }); } fn get_size(attrs: &SurfaceAttributes) -> Option<(i32, i32)> { @@ -143,38 +96,70 @@ fn get_size(attrs: &SurfaceAttributes) -> Option<(i32, i32)> { .map(|(x, y)| (x as i32, y as i32)) } -pub type MyWindowMap = WindowMap< - SurfaceData, - Roles, - Rc>>, - (), - fn(&SurfaceAttributes) -> Option<(i32, i32)>, ->; +pub type MyWindowMap = + WindowMap) -> Option<(i32, i32)>>; pub fn init_shell( - evl: &mut EventLoop, log: ::slog::Logger, data: Rc>> + display: &mut Display, + looptoken: LoopToken, + log: ::slog::Logger, + egl_display: Rc>>, ) -> ( - CompositorToken>>>, - StateToken>>, ()>>, + CompositorToken, + Arc>>, Rc>, ) { - let (compositor_token, _, _) = compositor_init(evl, surface_implementation(), data, log.clone()); - - let window_map = Rc::new(RefCell::new(WindowMap::<_, _, _, (), _>::new( - compositor_token, - get_size as _, - ))); - - let (shell_state_token, _, _) = shell_init( - evl, - compositor_token, - shell_implementation(), - ShellIData { - token: compositor_token, - window_map: window_map.clone(), + // Create the compositor + let c_egl_display = egl_display.clone(); + let (compositor_token, _, _) = compositor_init( + display, + looptoken.clone(), + move |request, (surface, ctoken)| match request { + SurfaceEvent::Commit => surface_commit(&surface, ctoken, &*c_egl_display), + SurfaceEvent::Frame { callback } => { + // TODO: uncomment when https://github.com/rust-lang/rust/issues/50153 is fixed + // callback.implement(|e, _| match e {}, None::).send(wl_callback::Event::Done { callback_data: 0}) + } }, log.clone(), ); - (compositor_token, shell_state_token, window_map) + // Init a window map, to track the location of our windows + let window_map = Rc::new(RefCell::new(WindowMap::<_, _, (), _>::new( + compositor_token, + get_size as _, + ))); + + // init the xdg_shell + let shell_window_map = window_map.clone(); + let (shell_state, _, _) = xdg_shell_init( + display, + looptoken, + compositor_token.clone(), + move |shell_event, ()| match shell_event { + ShellEvent::NewToplevel { surface } => { + // place the window at a random location in the [0;300]x[0;300] square + use rand::distributions::{IndependentSample, Range}; + let range = Range::new(0, 300); + let mut rng = rand::thread_rng(); + let x = range.ind_sample(&mut rng); + let y = range.ind_sample(&mut rng); + surface.send_configure(ToplevelConfigure { + size: None, + states: vec![], + serial: 42, + }); + shell_window_map.borrow_mut().insert(surface, (x, y)); + } + ShellEvent::NewPopup { surface } => surface.send_configure(PopupConfigure { + size: (10, 10), + position: (10, 10), + serial: 42, + }), + _ => (), + }, + log.clone(), + ); + + (compositor_token, shell_state, window_map) } diff --git a/examples/helpers/window_map.rs b/examples/helpers/window_map.rs index 979b4c1..71a401a 100644 --- a/examples/helpers/window_map.rs +++ b/examples/helpers/window_map.rs @@ -1,27 +1,29 @@ use smithay::utils::Rectangle; use smithay::wayland::compositor::{CompositorToken, SubsurfaceRole, SurfaceAttributes, TraversalAction}; use smithay::wayland::compositor::roles::Role; -use smithay::wayland::shell::{ShellSurfaceRole, ToplevelSurface}; +use smithay::wayland::shell::xdg::{ShellSurfaceRole, ToplevelSurface}; use wayland_server::Resource; use wayland_server::protocol::wl_surface; -struct Window { +struct Window { location: (i32, i32), surface: Rectangle, - toplevel: ToplevelSurface, + toplevel: ToplevelSurface, } -impl Window +impl Window where U: 'static, R: Role + Role + 'static, - CID: 'static, SD: 'static, { // Find the topmost surface under this point if any and the location of this point in the surface fn matching( - &self, point: (f64, f64), ctoken: CompositorToken, get_size: F - ) -> Option<(wl_surface::WlSurface, (f64, f64))> + &self, + point: (f64, f64), + ctoken: CompositorToken, + get_size: F, + ) -> Option<(Resource, (f64, f64))> where F: Fn(&SurfaceAttributes) -> Option<(i32, i32)>, { @@ -37,8 +39,8 @@ where |wl_surface, attributes, role, &(mut x, mut y)| { if let Some((w, h)) = get_size(attributes) { if let Ok(subdata) = Role::::data(role) { - x += subdata.x; - y += subdata.y; + x += subdata.location.0; + y += subdata.location.1; } let my_rect = Rectangle { x, @@ -47,9 +49,10 @@ where height: h, }; if my_rect.contains((point.0 as i32, point.1 as i32)) { - found = wl_surface - .clone() - .map(|s| (s, (point.0 - my_rect.x as f64, point.1 - my_rect.y as f64))); + found = Some(( + wl_surface.clone(), + (point.0 - my_rect.x as f64, point.1 - my_rect.y as f64), + )); TraversalAction::Break } else { TraversalAction::DoChildren((x, y)) @@ -63,7 +66,7 @@ where found } - fn self_update(&mut self, ctoken: CompositorToken, get_size: F) + fn self_update(&mut self, ctoken: CompositorToken, get_size: F) where F: Fn(&SurfaceAttributes) -> Option<(i32, i32)>, { @@ -76,8 +79,8 @@ where |_, attributes, role, &(mut x, mut y)| { if let Some((w, h)) = get_size(attributes) { if let Ok(subdata) = Role::::data(role) { - x += subdata.x; - y += subdata.y; + x += subdata.location.0; + y += subdata.location.1; } // update the bounding box if x < min_x { @@ -108,21 +111,20 @@ where } } -pub struct WindowMap { - ctoken: CompositorToken, - windows: Vec>, +pub struct WindowMap { + ctoken: CompositorToken, + windows: Vec>, get_size: F, } -impl WindowMap +impl WindowMap where F: Fn(&SurfaceAttributes) -> Option<(i32, i32)>, U: 'static, R: Role + Role + 'static, - CID: 'static, SD: 'static, { - pub fn new(ctoken: CompositorToken, get_size: F) -> WindowMap { + pub fn new(ctoken: CompositorToken, get_size: F) -> WindowMap { WindowMap { ctoken: ctoken, windows: Vec::new(), @@ -130,7 +132,7 @@ where } } - pub fn insert(&mut self, toplevel: ToplevelSurface, location: (i32, i32)) { + pub fn insert(&mut self, toplevel: ToplevelSurface, location: (i32, i32)) { let mut window = Window { location: location, surface: Rectangle { @@ -145,7 +147,10 @@ where self.windows.insert(0, window); } - pub fn get_surface_under(&self, point: (f64, f64)) -> Option<(wl_surface::WlSurface, (f64, f64))> { + pub fn get_surface_under( + &self, + point: (f64, f64), + ) -> Option<(Resource, (f64, f64))> { for w in &self.windows { if let Some(surface) = w.matching(point, self.ctoken, &self.get_size) { return Some(surface); @@ -155,8 +160,9 @@ where } pub fn get_surface_and_bring_to_top( - &mut self, point: (f64, f64) - ) -> Option<(wl_surface::WlSurface, (f64, f64))> { + &mut self, + point: (f64, f64), + ) -> Option<(Resource, (f64, f64))> { let mut found = None; for (i, w) in self.windows.iter().enumerate() { if let Some(surface) = w.matching(point, self.ctoken, &self.get_size) { @@ -175,7 +181,7 @@ where pub fn with_windows_from_bottom_to_top(&self, mut f: Func) where - Func: FnMut(&ToplevelSurface, (i32, i32)), + Func: FnMut(&ToplevelSurface, (i32, i32)), { for w in self.windows.iter().rev() { f(&w.toplevel, w.location) diff --git a/examples/udev.rs b/examples/udev.rs index 6cbe5dc..862e6be 100644 --- a/examples/udev.rs +++ b/examples/udev.rs @@ -53,9 +53,9 @@ use std::rc::Rc; use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; use std::time::Duration; -use wayland_server::{Display, EventLoopHandle}; +use wayland_server::Display; +use wayland_server::commons::downcast_impl; use wayland_server::protocol::{wl_output, wl_pointer}; -use wayland_server::sources::EventSource; use xkbcommon::xkb::keysyms as xkb; struct LibinputInputHandler { @@ -78,18 +78,16 @@ impl LibinputInputHandler { } impl InputHandler for LibinputInputHandler { - fn on_seat_created(&mut self, _evlh: &mut EventLoopHandle, _: &input::Seat) { + fn on_seat_created(&mut self, _: &input::Seat) { /* we just create a single static one */ } - fn on_seat_destroyed(&mut self, _evlh: &mut EventLoopHandle, _: &input::Seat) { + fn on_seat_destroyed(&mut self, _: &input::Seat) { /* we just create a single static one */ } - fn on_seat_changed(&mut self, _evlh: &mut EventLoopHandle, _: &input::Seat) { + fn on_seat_changed(&mut self, _: &input::Seat) { /* we just create a single static one */ } - fn on_keyboard_key( - &mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, evt: event::keyboard::KeyboardKeyEvent - ) { + fn on_keyboard_key(&mut self, _: &input::Seat, evt: event::keyboard::KeyboardKeyEvent) { let keycode = evt.key(); let state = evt.state(); debug!(self.log, "key"; "keycode" => keycode, "state" => format!("{:?}", state)); @@ -100,8 +98,9 @@ impl InputHandler for LibinputInputHandler { let running = &self.running; let mut session = &mut self.session; let log = &self.log; + let time = Event::time(&evt); self.keyboard - .input(keycode, state, serial, move |modifiers, keysym| { + .input(keycode, state, serial, time, move |modifiers, keysym| { debug!(log, "keysym"; "state" => format!("{:?}", state), "mods" => format!("{:?}", modifiers), "keysym" => xkbcommon::xkb::keysym_get_name(keysym)); if modifiers.ctrl && modifiers.alt && keysym == xkb::KEY_BackSpace && state == KeyState::Pressed @@ -132,9 +131,7 @@ impl InputHandler for LibinputInputHandler { } }); } - fn on_pointer_move( - &mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, evt: event::pointer::PointerMotionEvent - ) { + fn on_pointer_move(&mut self, _: &input::Seat, evt: event::pointer::PointerMotionEvent) { let (x, y) = (evt.dx(), evt.dy()); let serial = self.next_serial(); let mut location = self.pointer_location.borrow_mut(); @@ -149,10 +146,7 @@ impl InputHandler for LibinputInputHandler { evt.time(), ); } - fn on_pointer_move_absolute( - &mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, - evt: event::pointer::PointerMotionAbsoluteEvent, - ) { + fn on_pointer_move_absolute(&mut self, _: &input::Seat, evt: event::pointer::PointerMotionAbsoluteEvent) { let (x, y) = ( evt.absolute_x_transformed(self.screen_size.0), evt.absolute_y_transformed(self.screen_size.1), @@ -166,9 +160,7 @@ impl InputHandler for LibinputInputHandler { evt.time(), ); } - fn on_pointer_button( - &mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, evt: event::pointer::PointerButtonEvent - ) { + fn on_pointer_button(&mut self, _: &input::Seat, evt: event::pointer::PointerButtonEvent) { let serial = self.next_serial(); let button = evt.button(); let state = match evt.state() { @@ -185,9 +177,7 @@ impl InputHandler for LibinputInputHandler { }; self.pointer.button(button, state, serial, evt.time()); } - fn on_pointer_axis( - &mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, evt: event::pointer::PointerAxisEvent - ) { + fn on_pointer_axis(&mut self, _: &input::Seat, evt: event::pointer::PointerAxisEvent) { let source = match evt.source() { input::AxisSource::Continuous => wayland_server::protocol::wl_pointer::AxisSource::Continuous, input::AxisSource::Finger => wayland_server::protocol::wl_pointer::AxisSource::Finger, @@ -244,30 +234,22 @@ impl InputHandler for LibinputInputHandler { event.done(); } } - fn on_touch_down( - &mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, _: event::touch::TouchDownEvent - ) { + fn on_touch_down(&mut self, _: &input::Seat, _: event::touch::TouchDownEvent) { /* not done in this example */ } - fn on_touch_motion( - &mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, _: event::touch::TouchMotionEvent - ) { + fn on_touch_motion(&mut self, _: &input::Seat, _: event::touch::TouchMotionEvent) { /* not done in this example */ } - fn on_touch_up(&mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, _: event::touch::TouchUpEvent) { + fn on_touch_up(&mut self, _: &input::Seat, _: event::touch::TouchUpEvent) { /* not done in this example */ } - fn on_touch_cancel( - &mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, _: event::touch::TouchCancelEvent - ) { + fn on_touch_cancel(&mut self, _: &input::Seat, _: event::touch::TouchCancelEvent) { /* not done in this example */ } - fn on_touch_frame( - &mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, _: event::touch::TouchFrameEvent - ) { + fn on_touch_frame(&mut self, _: &input::Seat, _: event::touch::TouchFrameEvent) { /* not done in this example */ } - fn on_input_config_changed(&mut self, _evlh: &mut EventLoopHandle, _: &mut [LibinputDevice]) { + fn on_input_config_changed(&mut self, _: &mut [LibinputDevice]) { /* not done in this example */ } } @@ -284,7 +266,7 @@ fn main() { ); // Initialize the wayland server - let (mut display, mut event_loop) = wayland_server::create_display(); + let (mut display, mut event_loop) = wayland_server::Display::new(); /* * Add a listening socket @@ -292,15 +274,24 @@ fn main() { let name = display.add_socket_auto().unwrap().into_string().unwrap(); println!("Listening on socket: {}", name); env::set_var("WAYLAND_DISPLAY", name); - let display = Rc::new(display); + let display = Rc::new(RefCell::new(display)); /* * Initialize the compositor */ - init_shm_global(&mut event_loop, vec![], log.clone()); + init_shm_global( + &mut display.borrow_mut(), + event_loop.token(), + vec![], + log.clone(), + ); - let (compositor_token, _shell_state_token, window_map) = - init_shell(&mut event_loop, log.clone(), active_egl_context.clone()); + let (compositor_token, _shell_state_token, window_map) = init_shell( + &mut display.borrow_mut(), + event_loop.token(), + log.clone(), + active_egl_context.clone(), + ); /* * Initialize session @@ -321,7 +312,7 @@ fn main() { let bytes = include_bytes!("resources/cursor2.rgba"); let mut udev_backend = UdevBackend::new( - &mut event_loop, + event_loop.token(), &context, session.clone(), UdevHandlerImpl { @@ -340,17 +331,21 @@ fn main() { let udev_session_id = notifier.register(&mut udev_backend); - let (seat_token, _) = Seat::new(&mut event_loop, session.seat().into(), log.clone()); + let (mut w_seat, _) = Seat::new( + &mut display.borrow_mut(), + event_loop.token(), + session.seat().into(), + log.clone(), + ); - let pointer = event_loop.state().get_mut(&seat_token).add_pointer(); - let keyboard = event_loop - .state() - .get_mut(&seat_token) + let pointer = w_seat.add_pointer(); + let keyboard = w_seat .add_keyboard("", "", "", None, 1000, 500) .expect("Failed to initialize the keyboard"); - let (output_token, _output_global) = Output::new( - &mut event_loop, + let (output, _output_global) = Output::new( + &mut display.borrow_mut(), + event_loop.token(), "Drm".into(), PhysicalProperties { width: 0, @@ -363,26 +358,20 @@ fn main() { ); let (w, h) = (1920, 1080); // Hardcode full-hd res - event_loop - .state() - .get_mut(&output_token) - .change_current_state( - Some(Mode { - width: w as i32, - height: h as i32, - refresh: 60_000, - }), - None, - None, - ); - event_loop - .state() - .get_mut(&output_token) - .set_preferred(Mode { + output.change_current_state( + Some(Mode { width: w as i32, height: h as i32, refresh: 60_000, - }); + }), + None, + None, + ); + output.set_preferred(Mode { + width: w as i32, + height: h as i32, + refresh: 60_000, + }); /* * Initialize libinput backend @@ -392,28 +381,25 @@ fn main() { let libinput_session_id = notifier.register(&mut libinput_context); libinput_context.udev_assign_seat(&seat).unwrap(); let mut libinput_backend = LibinputInputBackend::new(libinput_context, log.clone()); - libinput_backend.set_handler( - &mut event_loop, - LibinputInputHandler { - log: log.clone(), - pointer, - keyboard, - window_map: window_map.clone(), - pointer_location, - screen_size: (w, h), - serial: 0, - session: session, - running: running.clone(), - }, - ); - let libinput_event_source = libinput_bind(libinput_backend, &mut event_loop) + libinput_backend.set_handler(LibinputInputHandler { + log: log.clone(), + pointer, + keyboard, + window_map: window_map.clone(), + pointer_location, + screen_size: (w, h), + serial: 0, + session: session, + running: running.clone(), + }); + let libinput_event_source = libinput_bind(libinput_backend, event_loop.token()) .map_err(|(err, _)| err) .unwrap(); - let session_event_source = auto_session_bind(notifier, &mut event_loop) + let session_event_source = auto_session_bind(notifier, &event_loop.token()) .map_err(|(err, _)| err) .unwrap(); - let udev_event_source = udev_backend_bind(&mut event_loop, udev_backend) + let udev_event_source = udev_backend_bind(&event_loop.token(), udev_backend) .map_err(|(err, _)| err) .unwrap(); @@ -421,7 +407,7 @@ fn main() { if let Err(_) = event_loop.dispatch(Some(16)) { running.store(false, Ordering::SeqCst); } else { - display.flush_clients(); + display.borrow_mut().flush_clients(); window_map.borrow_mut().refresh(); } } @@ -435,14 +421,15 @@ fn main() { libinput_event_source.remove(); // destroy the udev backend freeing the drm devices - udev_event_source.remove().close(&mut event_loop) + udev_backend = *(downcast_impl(udev_event_source.remove()).unwrap_or_else(|_| unreachable!())); + udev_backend.close(); } struct UdevHandlerImpl { - compositor_token: CompositorToken>>>, + compositor_token: CompositorToken, active_egl_context: Rc>>, backends: HashMap>>>>>, - display: Rc, + display: Rc>, primary_gpu: Option, window_map: Rc>, pointer_location: Rc>, @@ -452,7 +439,8 @@ struct UdevHandlerImpl { impl UdevHandlerImpl { pub fn scan_connectors( - &self, device: &mut DrmDevice + &self, + device: &mut DrmDevice, ) -> HashMap>> { // Get a set of all modesetting resource handles (excluding planes): let res_handles = device.resource_handles().unwrap(); @@ -511,12 +499,10 @@ impl UdevHandlerImpl { } impl UdevHandler for UdevHandlerImpl { - fn device_added( - &mut self, _evlh: &mut EventLoopHandle, device: &mut DrmDevice - ) -> Option { + fn device_added(&mut self, device: &mut DrmDevice) -> Option { // init hardware acceleration on the primary gpu. if device.dev_path().and_then(|path| path.canonicalize().ok()) == self.primary_gpu { - *self.active_egl_context.borrow_mut() = device.bind_wl_display(&*self.display).ok(); + *self.active_egl_context.borrow_mut() = device.bind_wl_display(&*self.display.borrow()).ok(); } let backends = Rc::new(RefCell::new(self.scan_connectors(device))); @@ -531,13 +517,13 @@ impl UdevHandler for UdevHandlerImpl { }) } - fn device_changed(&mut self, _evlh: &mut EventLoopHandle, device: &mut DrmDevice) { + fn device_changed(&mut self, device: &mut DrmDevice) { //quick and dirt, just re-init all backends let backends = self.backends.get(&device.device_id()).unwrap(); *backends.borrow_mut() = self.scan_connectors(device); } - fn device_removed(&mut self, _evlh: &mut EventLoopHandle, device: &mut DrmDevice) { + fn device_removed(&mut self, device: &mut DrmDevice) { // drop the backends on this side self.backends.remove(&device.device_id()); @@ -547,13 +533,13 @@ impl UdevHandler for UdevHandlerImpl { } } - fn error(&mut self, _evlh: &mut EventLoopHandle, error: IoError) { + fn error(&mut self, error: IoError) { error!(self.logger, "{:?}", error); } } pub struct DrmHandlerImpl { - compositor_token: CompositorToken>>>, + compositor_token: CompositorToken, backends: Rc>>>>, window_map: Rc>, pointer_location: Rc>, @@ -562,8 +548,11 @@ pub struct DrmHandlerImpl { impl DrmHandler for DrmHandlerImpl { fn ready( - &mut self, _evlh: &mut EventLoopHandle, _device: &mut DrmDevice, - crtc: crtc::Handle, _frame: u32, _duration: Duration, + &mut self, + _device: &mut DrmDevice, + crtc: crtc::Handle, + _frame: u32, + _duration: Duration, ) { if let Some(drawer) = self.backends.borrow().get(&crtc) { { @@ -616,8 +605,8 @@ impl DrmHandler for DrmHandlerImpl { if let Some(ref texture) = attributes.user_data.texture { if let Ok(subdata) = Role::::data(role) { - x += subdata.x; - y += subdata.y; + x += subdata.location.0; + y += subdata.location.1; } info!(self.logger, "Render window"); drawer.render_texture( @@ -655,9 +644,7 @@ impl DrmHandler for DrmHandlerImpl { } } - fn error( - &mut self, _evlh: &mut EventLoopHandle, _device: &mut DrmDevice, error: DrmError - ) { + fn error(&mut self, _device: &mut DrmDevice, error: DrmError) { error!(self.logger, "{:?}", error); } } diff --git a/examples/winit.rs b/examples/winit.rs index 24ff502..e388c1d 100644 --- a/examples/winit.rs +++ b/examples/winit.rs @@ -26,7 +26,7 @@ use smithay::wayland::seat::{KeyboardHandle, PointerHandle, Seat}; use smithay::wayland::shm::init_shm_global; use std::cell::RefCell; use std::rc::Rc; -use wayland_server::EventLoopHandle; +use wayland_server::Display; use wayland_server::protocol::{wl_output, wl_pointer}; struct WinitInputHandler { @@ -46,30 +46,27 @@ impl WinitInputHandler { } impl InputHandler for WinitInputHandler { - fn on_seat_created(&mut self, _evlh: &mut EventLoopHandle, _: &input::Seat) { + fn on_seat_created(&mut self, _: &input::Seat) { /* never happens with winit */ } - fn on_seat_destroyed(&mut self, _evlh: &mut EventLoopHandle, _: &input::Seat) { + fn on_seat_destroyed(&mut self, _: &input::Seat) { /* never happens with winit */ } - fn on_seat_changed(&mut self, _evlh: &mut EventLoopHandle, _: &input::Seat) { + fn on_seat_changed(&mut self, _: &input::Seat) { /* never happens with winit */ } - fn on_keyboard_key( - &mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, evt: winit::WinitKeyboardInputEvent - ) { + fn on_keyboard_key(&mut self, _: &input::Seat, evt: winit::WinitKeyboardInputEvent) { let keycode = evt.key_code(); let state = evt.state(); debug!(self.log, "key"; "keycode" => keycode, "state" => format!("{:?}", state)); let serial = self.next_serial(); - self.keyboard.input(keycode, state, serial, |_, _| true); + self.keyboard + .input(keycode, state, serial, evt.time(), |_, _| true); } - fn on_pointer_move(&mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, _: input::UnusedEvent) { + fn on_pointer_move(&mut self, _: &input::Seat, _: input::UnusedEvent) { /* never happens with winit */ } - fn on_pointer_move_absolute( - &mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, evt: winit::WinitMouseMovedEvent - ) { + fn on_pointer_move_absolute(&mut self, _: &input::Seat, evt: winit::WinitMouseMovedEvent) { // on winit, mouse events are already in pixel coordinates let (x, y) = evt.position(); self.pointer_location = (x, y); @@ -81,9 +78,7 @@ impl InputHandler for WinitInputHandler { evt.time(), ); } - fn on_pointer_button( - &mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, evt: winit::WinitMouseInputEvent - ) { + fn on_pointer_button(&mut self, _: &input::Seat, evt: winit::WinitMouseInputEvent) { let serial = self.next_serial(); let button = match evt.button() { input::MouseButton::Left => 0x110, @@ -105,9 +100,7 @@ impl InputHandler for WinitInputHandler { }; self.pointer.button(button, state, serial, evt.time()); } - fn on_pointer_axis( - &mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, evt: winit::WinitMouseWheelEvent - ) { + fn on_pointer_axis(&mut self, _: &input::Seat, evt: winit::WinitMouseWheelEvent) { let source = match evt.source() { input::AxisSource::Continuous => wayland_server::protocol::wl_pointer::AxisSource::Continuous, input::AxisSource::Wheel => wayland_server::protocol::wl_pointer::AxisSource::Wheel, @@ -152,28 +145,22 @@ impl InputHandler for WinitInputHandler { event.done(); } } - fn on_touch_down( - &mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, _: winit::WinitTouchStartedEvent - ) { + fn on_touch_down(&mut self, _: &input::Seat, _: winit::WinitTouchStartedEvent) { /* not done in this example */ } - fn on_touch_motion( - &mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, _: winit::WinitTouchMovedEvent - ) { + fn on_touch_motion(&mut self, _: &input::Seat, _: winit::WinitTouchMovedEvent) { /* not done in this example */ } - fn on_touch_up(&mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, _: winit::WinitTouchEndedEvent) { + fn on_touch_up(&mut self, _: &input::Seat, _: winit::WinitTouchEndedEvent) { /* not done in this example */ } - fn on_touch_cancel( - &mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, _: winit::WinitTouchCancelledEvent - ) { + fn on_touch_cancel(&mut self, _: &input::Seat, _: winit::WinitTouchCancelledEvent) { /* not done in this example */ } - fn on_touch_frame(&mut self, _evlh: &mut EventLoopHandle, _: &input::Seat, _: input::UnusedEvent) { + fn on_touch_frame(&mut self, _: &input::Seat, _: input::UnusedEvent) { /* never happens with winit */ } - fn on_input_config_changed(&mut self, _evlh: &mut EventLoopHandle, _: &mut ()) { + fn on_input_config_changed(&mut self, _: &mut ()) { /* never happens with winit */ } } @@ -188,7 +175,7 @@ fn main() { // Initialize a simple backend for testing let (renderer, mut input) = winit::init(log.clone()).unwrap(); - let (mut display, mut event_loop) = wayland_server::create_display(); + let (mut display, mut event_loop) = wayland_server::Display::new(); let egl_display = Rc::new(RefCell::new( if let Ok(egl_display) = renderer.bind_wl_display(&display) { @@ -206,22 +193,25 @@ fn main() { * Initialize the globals */ - init_shm_global(&mut event_loop, vec![], log.clone()); + init_shm_global(&mut display, event_loop.token(), vec![], log.clone()); let (compositor_token, _shell_state_token, window_map) = - init_shell(&mut event_loop, log.clone(), egl_display); + init_shell(&mut display, event_loop.token(), log.clone(), egl_display); - let (seat_token, _) = Seat::new(&mut event_loop, "winit".into(), log.clone()); + let (mut seat, _) = Seat::new( + &mut display, + event_loop.token(), + "winit".into(), + log.clone(), + ); - let pointer = event_loop.state().get_mut(&seat_token).add_pointer(); - let keyboard = event_loop - .state() - .get_mut(&seat_token) - .add_keyboard("", "fr", "oss", None, 1000, 500) + let pointer = seat.add_pointer(); + let keyboard = seat.add_keyboard("", "fr", "oss", None, 1000, 500) .expect("Failed to initialize the keyboard"); - let (output_token, _output_global) = Output::new( - &mut event_loop, + let (output, _) = Output::new( + &mut display, + event_loop.token(), "Winit".into(), PhysicalProperties { width: 0, @@ -233,38 +223,29 @@ fn main() { log.clone(), ); - event_loop - .state() - .get_mut(&output_token) - .change_current_state( - Some(Mode { - width: w as i32, - height: h as i32, - refresh: 60_000, - }), - None, - None, - ); - event_loop - .state() - .get_mut(&output_token) - .set_preferred(Mode { + output.change_current_state( + Some(Mode { width: w as i32, height: h as i32, refresh: 60_000, - }); - - input.set_handler( - &mut event_loop, - WinitInputHandler { - log: log.clone(), - pointer, - keyboard, - window_map: window_map.clone(), - pointer_location: (0.0, 0.0), - serial: 0, - }, + }), + None, + None, ); + output.set_preferred(Mode { + width: w as i32, + height: h as i32, + refresh: 60_000, + }); + + input.set_handler(WinitInputHandler { + log: log.clone(), + pointer, + keyboard, + window_map: window_map.clone(), + pointer_location: (0.0, 0.0), + serial: 0, + }); /* * Add a listening socket: @@ -273,7 +254,7 @@ fn main() { println!("Listening on socket: {}", name); loop { - input.dispatch_new_events(&mut event_loop).unwrap(); + input.dispatch_new_events().unwrap(); let mut frame = drawer.draw(); frame.clear(None, Some((0.8, 0.8, 0.9, 1.0)), false, Some(1.0), None); @@ -320,8 +301,8 @@ fn main() { if let Some(ref texture) = attributes.user_data.texture { if let Ok(subdata) = Role::::data(role) { - x += subdata.x; - y += subdata.y; + x += subdata.location.0; + y += subdata.location.1; } drawer.render_texture( &mut frame,