From 0de5694a1860ceaf0d1d9516b36c8cfc7d5a74d8 Mon Sep 17 00:00:00 2001 From: Victor Berger Date: Wed, 20 Sep 2017 15:03:58 +0200 Subject: [PATCH] Update example to new API --- examples/helpers/implementations.rs | 95 ++++++++++++++ examples/helpers/mod.rs | 2 + examples/simple.rs | 197 ++-------------------------- 3 files changed, 111 insertions(+), 183 deletions(-) create mode 100644 examples/helpers/implementations.rs diff --git a/examples/helpers/implementations.rs b/examples/helpers/implementations.rs new file mode 100644 index 0000000..231c3f8 --- /dev/null +++ b/examples/helpers/implementations.rs @@ -0,0 +1,95 @@ +use rand; +use smithay::compositor::{CompositorToken, SurfaceUserImplementation}; +use smithay::shell::{PopupConfigure, ShellSurfaceRole, ShellSurfaceUserImplementation, ToplevelConfigure}; +use smithay::shm::with_buffer_contents; + +define_roles!(Roles => [ ShellSurface, ShellSurfaceRole ] ); + +#[derive(Default)] +pub struct SurfaceData { + pub buffer: Option<(Vec, (u32, u32))>, + pub location: Option<(i32, i32)>, +} + +pub fn surface_implementation() -> SurfaceUserImplementation { + SurfaceUserImplementation { + commit: |_, _, 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 + with_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.buffer = + Some((new_vec, (data.width as u32, data.height as u32))); + }).unwrap(); + buffer.release(); + } + Some(None) => { + // erase the contents + attributes.user_data.buffer = None; + } + None => {} + } + }); + }, + frame: |_, _, _, callback, _| { + callback.done(0); + }, + } +} + +pub fn shell_implementation( + ) + -> ShellSurfaceUserImplementation, ()> +{ + ShellSurfaceUserImplementation { + new_client: |_, _, _| {}, + client_pong: |_, _, _| {}, + new_toplevel: |_, token, toplevel| { + let wl_surface = toplevel.get_surface().unwrap(); + token.with_surface_data(wl_surface, |data| { + // 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); + data.user_data.location = Some((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: |_, _, _, _, _, _, _| {}, + } +} diff --git a/examples/helpers/mod.rs b/examples/helpers/mod.rs index 407fec4..36e6945 100644 --- a/examples/helpers/mod.rs +++ b/examples/helpers/mod.rs @@ -1,3 +1,5 @@ mod glium; +mod implementations; pub use self::glium::GliumDrawer; +pub use self::implementations::*; diff --git a/examples/simple.rs b/examples/simple.rs index 2a48d6b..38ae92a 100644 --- a/examples/simple.rs +++ b/examples/simple.rs @@ -13,151 +13,15 @@ extern crate wayland_server; mod helpers; use glium::Surface; - -use helpers::GliumDrawer; +use helpers::{shell_implementation, surface_implementation, GliumDrawer}; use slog::{Drain, Logger}; - use smithay::backend::graphics::glium::IntoGlium; use smithay::backend::input::InputBackend; use smithay::backend::winit; -use smithay::compositor::{self, CompositorHandler, CompositorToken, SubsurfaceRole, TraversalAction}; +use smithay::compositor::{compositor_init, SubsurfaceRole, TraversalAction}; use smithay::compositor::roles::Role; -use smithay::shell::{self, PopupConfigure, PopupSurface, ShellClient, ShellHandler, ShellSurfaceRole, - ToplevelConfigure, ToplevelSurface}; -use smithay::shm::{ShmGlobal, ShmToken}; - -use wayland_protocols::unstable::xdg_shell::server::{zxdg_shell_v6, zxdg_toplevel_v6}; - -use wayland_server::{Client, EventLoopHandle}; -use wayland_server::protocol::{wl_callback, wl_compositor, wl_output, wl_seat, wl_shell, wl_shm, - wl_subcompositor, wl_surface}; - -define_roles!(Roles => [ ShellSurface, ShellSurfaceRole ] ); - -struct SurfaceHandler { - shm_token: ShmToken, -} - -#[derive(Default)] -struct SurfaceData { - buffer: Option<(Vec, (u32, u32))>, - location: Option<(i32, i32)>, -} - -impl compositor::Handler for SurfaceHandler { - fn commit(&mut self, _evlh: &mut EventLoopHandle, _client: &Client, surface: &wl_surface::WlSurface, - token: CompositorToken) { - // 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 - self.shm_token - .with_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.buffer = - Some((new_vec, (data.width as u32, data.height as u32))); - }) - .unwrap(); - buffer.release(); - } - Some(None) => { - // erase the contents - attributes.user_data.buffer = None; - } - None => {} - } - }); - } - - fn frame(&mut self, _evlh: &mut EventLoopHandle, _client: &Client, surface: &wl_surface::WlSurface, - callback: wl_callback::WlCallback, _token: CompositorToken) { - callback.done(0); - } -} - -struct ShellSurfaceHandler { - token: CompositorToken, -} - -impl ShellSurfaceHandler { - fn new(token: CompositorToken) -> ShellSurfaceHandler { - ShellSurfaceHandler { token } - } -} - -impl shell::Handler for ShellSurfaceHandler { - fn new_client(&mut self, _evlh: &mut EventLoopHandle, _client: ShellClient<()>) {} - fn client_pong(&mut self, _evlh: &mut EventLoopHandle, _client: ShellClient<()>) {} - fn new_toplevel(&mut self, _evlh: &mut EventLoopHandle, - surface: ToplevelSurface) - -> ToplevelConfigure { - let wl_surface = surface.get_surface().unwrap(); - self.token.with_surface_data(wl_surface, |data| { - // 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); - data.user_data.location = Some((x, y)) - }); - ToplevelConfigure { - size: None, - states: vec![], - serial: 42, - } - } - fn new_popup(&mut self, _evlh: &mut EventLoopHandle, - _surface: PopupSurface) - -> PopupConfigure { - PopupConfigure { - size: (10, 10), - position: (10, 10), - serial: 42, - } - } - fn move_(&mut self, _evlh: &mut EventLoopHandle, - _surface: ToplevelSurface, _seat: &wl_seat::WlSeat, - _serial: u32) { - } - fn resize(&mut self, _evlh: &mut EventLoopHandle, - _surface: ToplevelSurface, _seat: &wl_seat::WlSeat, - _serial: u32, _edges: zxdg_toplevel_v6::ResizeEdge) { - } - fn grab(&mut self, _evlh: &mut EventLoopHandle, - _surface: PopupSurface, _seat: &wl_seat::WlSeat, - _serial: u32) { - } - fn change_display_state(&mut self, _evlh: &mut EventLoopHandle, - _surface: ToplevelSurface, - _maximized: Option, _minimized: Option, _fullscreen: Option, - _output: Option<&wl_output::WlOutput>) - -> ToplevelConfigure { - ToplevelConfigure { - size: None, - states: vec![], - serial: 42, - } - } - fn show_window_menu(&mut self, _evlh: &mut EventLoopHandle, - _surface: ToplevelSurface, - _seat: &wl_seat::WlSeat, _serial: u32, _x: i32, _y: i32) { - } -} - - -type MyCompositorHandler = CompositorHandler; -type MyShellHandler = ShellHandler; +use smithay::shell::shell_init; +use smithay::shm::init_shm_global; fn main() { // A logger facility, here we use the terminal for this example @@ -172,51 +36,21 @@ fn main() { let (mut display, mut event_loop) = wayland_server::create_display(); /* - * Initialize wl_shm global + * Initialize the globals */ - // Insert the ShmGlobal as a handler to your event loop - // Here, we specify tha the standard Argb8888 and Xrgb8888 is the only supported. - let shm_handler_id = event_loop.add_handler_with_init(ShmGlobal::new(vec![], log.clone())); - // Register this handler to advertise a wl_shm global of version 1 - event_loop.register_global::(shm_handler_id, 1); - // retreive the token - let shm_token = { - let state = event_loop.state(); - state.get_handler::(shm_handler_id).get_token() - }; + init_shm_global(&mut event_loop, vec![], log.clone()); - /* - * Initialize the compositor global - */ - let compositor_handler_id = event_loop.add_handler_with_init(MyCompositorHandler::new( - SurfaceHandler { - shm_token: shm_token.clone(), - }, - log.clone(), - )); - // register it to handle wl_compositor and wl_subcompositor - event_loop.register_global::(compositor_handler_id, 4); - event_loop - .register_global::(compositor_handler_id, 1); - // retrieve the tokens - let compositor_token = { - let state = event_loop.state(); - state - .get_handler::(compositor_handler_id) - .get_token() - }; + let (compositor_token, _, _) = + compositor_init(&mut event_loop, surface_implementation(), (), log.clone()); - /* - * Initialize the shell global - */ - let shell_handler_id = event_loop.add_handler_with_init(MyShellHandler::new( - ShellSurfaceHandler::new(compositor_token), + let (shell_state_token, _, _) = shell_init( + &mut event_loop, + compositor_token, + shell_implementation(), compositor_token, log.clone(), - )); - event_loop.register_global::(shell_handler_id, 1); - event_loop.register_global::(shell_handler_id, 1); + ); /* * Initialize glium @@ -240,10 +74,7 @@ fn main() { { let screen_dimensions = context.get_framebuffer_dimensions(); let state = event_loop.state(); - for toplevel_surface in state - .get_handler::(shell_handler_id) - .toplevel_surfaces() - { + for toplevel_surface in state.get(&shell_state_token).toplevel_surfaces() { if let Some(wl_surface) = toplevel_surface.get_surface() { // this surface is a root of a subsurface tree that needs to be drawn let initial_place = compositor_token