diff --git a/anvil/src/buffer_utils.rs b/anvil/src/buffer_utils.rs index c568d9d..2112579 100644 --- a/anvil/src/buffer_utils.rs +++ b/anvil/src/buffer_utils.rs @@ -3,7 +3,7 @@ use std::{cell::RefCell, rc::Rc}; use slog::Logger; #[cfg(feature = "egl")] -use smithay::backend::egl::{BufferAccessError, EGLDisplay}; +use smithay::backend::egl::EGLDisplay; use smithay::{ reexports::wayland_server::protocol::wl_buffer::WlBuffer, wayland::shm::with_buffer_contents as shm_buffer_contents, diff --git a/anvil/src/shell.rs b/anvil/src/shell.rs index 15a1b83..8056bd5 100644 --- a/anvil/src/shell.rs +++ b/anvil/src/shell.rs @@ -17,7 +17,7 @@ use smithay::{ }, utils::Rectangle, wayland::{ - compositor::{compositor_init, CompositorToken, RegionAttributes, SurfaceAttributes, SurfaceEvent}, + compositor::{compositor_init, BufferAssignment, CompositorToken, RegionAttributes, SurfaceEvent}, data_device::DnDIconRole, seat::{AxisFrame, CursorImageRole, GrabStartData, PointerGrab, PointerInnerHandle, Seat}, shell::{ @@ -29,7 +29,6 @@ use smithay::{ XdgSurfacePendingState, XdgSurfaceRole, }, }, - SERIAL_COUNTER as SCOUNTER, }, }; @@ -734,7 +733,7 @@ fn surface_commit( // we retrieve the contents of the associated buffer and copy it match attributes.buffer.take() { - Some(Some((buffer, (_x, _y)))) => { + Some(BufferAssignment::NewBuffer { buffer, .. }) => { // new contents // TODO: handle hotspot coordinates if let Some(old_buffer) = data.buffer.replace(buffer) { @@ -744,7 +743,7 @@ fn surface_commit( // If this fails, the buffer will be discarded later by the drawing code. data.dimensions = buffer_utils.dimensions(data.buffer.as_ref().unwrap()); } - Some(None) => { + Some(BufferAssignment::Removed) => { // erase the contents if let Some(old_buffer) = data.buffer.take() { old_buffer.release(); diff --git a/anvil/src/udev.rs b/anvil/src/udev.rs index 418ab01..dfc59a5 100644 --- a/anvil/src/udev.rs +++ b/anvil/src/udev.rs @@ -1,6 +1,6 @@ use std::{ cell::RefCell, - collections::HashMap, + collections::hash_map::{Entry, HashMap}, io::Error as IoError, os::unix::io::{AsRawFd, RawFd}, path::PathBuf, @@ -264,7 +264,8 @@ pub fn run_udev(mut display: Display, mut event_loop: EventLoop, log if state.need_wayland_dispatch { display .borrow_mut() - .dispatch(std::time::Duration::from_millis(0), &mut state); + .dispatch(std::time::Duration::from_millis(0), &mut state) + .unwrap(); } display.borrow_mut().flush_clients(&mut state); window_map.borrow_mut().refresh(); @@ -284,19 +285,18 @@ pub fn run_udev(mut display: Display, mut event_loop: EventLoop, log Ok(()) } +struct BackendData { + id: S::Id, + event_source: Source>>, + surfaces: Rc>>>, +} + struct UdevHandlerImpl { compositor_token: CompositorToken, #[cfg(feature = "egl")] active_egl_context: Rc>>, session: AutoSession, - backends: HashMap< - dev_t, - ( - S::Id, - Source>>, - Rc>>>, - ), - >, + backends: HashMap>, display: Rc>, primary_gpu: Option, window_map: Rc>, @@ -340,14 +340,14 @@ impl UdevHandlerImpl { .collect::>(); for encoder_info in encoder_infos { for crtc in res_handles.filter_crtcs(encoder_info.possible_crtcs()) { - if !backends.contains_key(&crtc) { + if let Entry::Vacant(entry) = backends.entry(crtc) { let renderer = GliumDrawer::init( device.create_surface(crtc).unwrap(), egl_display.clone(), logger.clone(), ); - backends.insert(crtc, renderer); + entry.insert(renderer); break; } } @@ -471,17 +471,23 @@ impl UdevHandler for UdevHandlerImpl } } - self.backends - .insert(dev_id, (device_session_id, event_source, backends)); + self.backends.insert( + dev_id, + BackendData { + id: device_session_id, + event_source, + surfaces: backends, + }, + ); } } fn device_changed(&mut self, device: dev_t) { //quick and dirty, just re-init all backends - if let Some((_, ref mut evt_source, ref backends)) = self.backends.get_mut(&device) { - let source = evt_source.clone_inner(); + if let Some(ref mut backend_data) = self.backends.get_mut(&device) { + let source = backend_data.event_source.clone_inner(); let mut evented = source.borrow_mut(); - let mut backends = backends.borrow_mut(); + let mut backends = backend_data.surfaces.borrow_mut(); #[cfg(feature = "egl")] let new_backends = UdevHandlerImpl::::scan_connectors( &mut (*evented).0, @@ -511,12 +517,12 @@ impl UdevHandler for UdevHandlerImpl fn device_removed(&mut self, device: dev_t) { // drop the backends on this side - if let Some((id, evt_source, renderers)) = self.backends.remove(&device) { + if let Some(backend_data) = self.backends.remove(&device) { // drop surfaces - renderers.borrow_mut().clear(); + backend_data.surfaces.borrow_mut().clear(); debug!(self.logger, "Surfaces dropped"); - let device = Rc::try_unwrap(evt_source.remove().unwrap()) + let device = Rc::try_unwrap(backend_data.event_source.remove().unwrap()) .map_err(|_| "This should not happend") .unwrap() .into_inner() @@ -530,7 +536,7 @@ impl UdevHandler for UdevHandlerImpl } } - self.notifier.unregister(id); + self.notifier.unregister(backend_data.id); debug!(self.logger, "Dropping device"); } } diff --git a/anvil/src/winit.rs b/anvil/src/winit.rs index 9841f4f..c29c3bd 100644 --- a/anvil/src/winit.rs +++ b/anvil/src/winit.rs @@ -201,7 +201,9 @@ pub fn run_winit( running.store(false, Ordering::SeqCst); } else { if state.need_wayland_dispatch { - display.dispatch(std::time::Duration::from_millis(0), &mut state); + display + .dispatch(std::time::Duration::from_millis(0), &mut state) + .unwrap(); } display.flush_clients(&mut state); window_map.borrow_mut().refresh(); diff --git a/src/backend/drm/gbm/surface.rs b/src/backend/drm/gbm/surface.rs index 60d4f22..79c85ec 100644 --- a/src/backend/drm/gbm/surface.rs +++ b/src/backend/drm/gbm/surface.rs @@ -287,6 +287,11 @@ impl GbmSurface { /// *Note*: This might trigger a full modeset on the underlying device, /// potentially causing some flickering. In that case this operation is /// blocking until the crtc is in the desired state. + /// + /// # Safety + /// + /// When used in conjunction with an EGL context, this must be called exactly once + /// after page-flipping the associated context. pub unsafe fn page_flip(&self) -> ::std::result::Result<(), SwapBuffersError> { self.0.page_flip() } diff --git a/src/backend/drm/legacy/mod.rs b/src/backend/drm/legacy/mod.rs index 26a467d..9d5d502 100644 --- a/src/backend/drm/legacy/mod.rs +++ b/src/backend/drm/legacy/mod.rs @@ -66,8 +66,8 @@ pub enum Error { /// No encoder was found for a given connector on the set crtc #[error("No encoder found for the given connector '{connector:?}' on crtc `{crtc:?}`")] NoSuitableEncoder { - /// Connector info - connector: connector::Info, + /// Connector + connector: connector::Handle, /// CRTC crtc: crtc::Handle, }, diff --git a/src/backend/drm/legacy/surface.rs b/src/backend/drm/legacy/surface.rs index 232b9a6..53c178c 100644 --- a/src/backend/drm/legacy/surface.rs +++ b/src/backend/drm/legacy/surface.rs @@ -150,7 +150,7 @@ impl Surface for LegacyDrmSurfaceInternal { .all(|crtc_list| resource_handles.filter_crtcs(crtc_list).contains(&self.crtc)) { return Err(Error::NoSuitableEncoder { - connector: info, + connector: info.handle(), crtc: self.crtc, }); } @@ -158,7 +158,7 @@ impl Surface for LegacyDrmSurfaceInternal { pending.connectors.insert(conn); Ok(()) } else { - return Err(Error::ModeNotSuitable(pending.mode.unwrap())); + Err(Error::ModeNotSuitable(pending.mode.unwrap())) } } diff --git a/src/backend/drm/mod.rs b/src/backend/drm/mod.rs index c171435..c3204d6 100644 --- a/src/backend/drm/mod.rs +++ b/src/backend/drm/mod.rs @@ -114,10 +114,19 @@ pub trait Device: AsRawFd + DevPath { /// [`ResourceHandle`](drm::control::ResourceHandle) fn resource_handles(&self) -> Result::Error>; + /// Retrieve the information for a connector fn get_connector_info(&self, conn: connector::Handle) -> Result; + + /// Retrieve the information for a crtc fn get_crtc_info(&self, crtc: crtc::Handle) -> Result; + + /// Retrieve the information for an encoder fn get_encoder_info(&self, enc: encoder::Handle) -> Result; + + /// Retrieve the information for a framebuffer fn get_framebuffer_info(&self, fb: framebuffer::Handle) -> Result; + + /// Retrieve the information for a plane fn get_plane_info(&self, plane: plane::Handle) -> Result; } @@ -221,6 +230,9 @@ impl DevPath for A { } } +/// calloop source associated with a Device +pub type DrmSource = Generic>; + /// Bind a `Device` to an [`EventLoop`](calloop::EventLoop), /// /// This will cause it to recieve events and feed them into a previously @@ -228,7 +240,7 @@ impl DevPath for A { pub fn device_bind( handle: &LoopHandle, device: D, -) -> ::std::result::Result>>, InsertError>>> +) -> ::std::result::Result>, InsertError>> where D: Device, Data: 'static, diff --git a/src/backend/egl/context.rs b/src/backend/egl/context.rs index 1bd1571..5f0d409 100644 --- a/src/backend/egl/context.rs +++ b/src/backend/egl/context.rs @@ -446,7 +446,9 @@ impl> EGLContext { /// Returns the address of an OpenGL function. /// - /// Supposes that the context has been made current before this function is called. + /// # Safety + /// + /// The context must have been made current before this function is called. pub unsafe fn get_proc_address(&self, symbol: &str) -> *const c_void { let addr = CString::new(symbol.as_bytes()).unwrap(); let addr = addr.as_ptr(); diff --git a/src/backend/egl/mod.rs b/src/backend/egl/mod.rs index a4b4d90..6909538 100644 --- a/src/backend/egl/mod.rs +++ b/src/backend/egl/mod.rs @@ -183,7 +183,7 @@ impl EGLImages { /// /// This does only temporarily modify the OpenGL state any changes are reverted before returning. /// - /// # Unsafety + /// # Safety /// /// The given `tex_id` needs to be a valid GL texture otherwise undefined behavior might occur. #[cfg(feature = "renderer_gl")] diff --git a/src/backend/egl/native.rs b/src/backend/egl/native.rs index ad4c508..b7a6841 100644 --- a/src/backend/egl/native.rs +++ b/src/backend/egl/native.rs @@ -20,7 +20,7 @@ pub trait Backend { /// Return an [`EGLDisplay`](ffi::egl::types::EGLDisplay) based on this backend /// - /// # Unsafety + /// # Safety /// /// The returned [`EGLDisplay`](ffi::egl::types::EGLDisplay) needs to be a valid pointer for EGL, /// but there is no way to test that. @@ -154,7 +154,7 @@ unsafe impl NativeDisplay for WinitWindow { wegl::WlEglSurface::new_from_raw(surface as *mut _, size.width as i32, size.height as i32) }) } else { - return Err(Error::NonMatchingBackend("Wayland")); + Err(Error::NonMatchingBackend("Wayland")) } } } diff --git a/src/backend/egl/surface.rs b/src/backend/egl/surface.rs index 71d16ac..c3687d0 100644 --- a/src/backend/egl/surface.rs +++ b/src/backend/egl/surface.rs @@ -100,7 +100,7 @@ impl EGLSurface { /// Makes the OpenGL context the current context in the current thread. /// - /// # Unsafety + /// # Safety /// /// This function is marked unsafe, because the context cannot be made current /// on multiple threads. diff --git a/src/backend/graphics/errors.rs b/src/backend/graphics/errors.rs deleted file mode 100644 index c169d8d..0000000 --- a/src/backend/graphics/errors.rs +++ /dev/null @@ -1,44 +0,0 @@ -use std::error::Error; -use std::fmt; - -/// Error that can happen when swapping buffers. -#[derive(Debug, Clone, PartialEq)] -pub enum SwapBuffersError { - /// The corresponding context has been lost and needs to be recreated. - /// - /// All the objects associated to it (textures, buffers, programs, etc.) - /// need to be recreated from scratch. - /// - /// Operations will have no effect. Functions that read textures, buffers, etc. - /// will return uninitialized data instead. - ContextLost, - /// The buffers have already been swapped. - /// - /// This error can be returned when `swap_buffers` has been called multiple times - /// without any modification in between. - AlreadySwapped, - /// Unknown error - Unknown(u32), -} - -impl fmt::Display for SwapBuffersError { - fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - write!(formatter, "{}", self.description()) - } -} - -impl Error for SwapBuffersError { - fn description(&self) -> &str { - match *self { - SwapBuffersError::ContextLost => "The context has been lost, it needs to be recreated", - SwapBuffersError::AlreadySwapped => { - "Buffers are already swapped, swap_buffers was called too many times" - } - SwapBuffersError::Unknown(_) => "Unknown error occurred", - } - } - - fn cause(&self) -> Option<&dyn Error> { - None - } -} diff --git a/src/backend/graphics/gl.rs b/src/backend/graphics/gl.rs index 27fc86d..d0d04a0 100644 --- a/src/backend/graphics/gl.rs +++ b/src/backend/graphics/gl.rs @@ -19,7 +19,9 @@ pub trait GLGraphicsBackend { /// Returns the address of an OpenGL function. /// - /// Supposes that the context has been made current before this function is called. + /// # Safety + /// + /// The context must have been made current before this function is called. unsafe fn get_proc_address(&self, symbol: &str) -> *const c_void; /// Returns the dimensions of the window, or screen, etc in points. @@ -34,10 +36,9 @@ pub trait GLGraphicsBackend { /// Makes the OpenGL context the current context in the current thread. /// - /// # Unsafety + /// # Safety /// - /// This function is marked unsafe, because the context cannot be made current - /// on multiple threads. + /// The context cannot be made current on multiple threads. unsafe fn make_current(&self) -> Result<(), SwapBuffersError>; /// Returns the pixel format of the main framebuffer of the context. diff --git a/src/backend/graphics/mod.rs b/src/backend/graphics/mod.rs index 188e1c0..0fb18bf 100644 --- a/src/backend/graphics/mod.rs +++ b/src/backend/graphics/mod.rs @@ -2,9 +2,6 @@ //! //! Note: Not every API may be supported by every backend -mod errors; -pub use self::errors::*; - mod cursor; pub use self::cursor::*; @@ -17,3 +14,26 @@ pub mod gl; pub mod glium; #[cfg(feature = "renderer_software")] pub mod software; + +/// Error that can happen when swapping buffers. +#[derive(Debug, Clone, PartialEq, thiserror::Error)] +pub enum SwapBuffersError { + /// The corresponding context has been lost and needs to be recreated. + /// + /// All the objects associated to it (textures, buffers, programs, etc.) + /// need to be recreated from scratch. + /// + /// Operations will have no effect. Functions that read textures, buffers, etc. + /// will return uninitialized data instead. + #[error("The context has been lost, it needs to be recreated")] + ContextLost, + /// The buffers have already been swapped. + /// + /// This error can be returned when `swap_buffers` has been called multiple times + /// without any modification in between. + #[error("Buffers are already swapped, swap_buffers was called too many times")] + AlreadySwapped, + /// Unknown error + #[error("Unknown error: {0:x}")] + Unknown(u32), +} diff --git a/src/backend/libinput.rs b/src/backend/libinput.rs index b3c9b47..9c6059e 100644 --- a/src/backend/libinput.rs +++ b/src/backend/libinput.rs @@ -614,6 +614,9 @@ impl AsRawFd for LibinputInputBackend { } } +/// calloop source associated with the libinput backend +pub type LibinputSource = Generic>; + /// Binds a [`LibinputInputBackend`] to a given [`LoopHandle`]. /// /// Automatically feeds the backend with incoming events without any manual calls to @@ -621,10 +624,7 @@ impl AsRawFd for LibinputInputBackend { pub fn libinput_bind( backend: LibinputInputBackend, handle: LoopHandle, -) -> ::std::result::Result< - Source>>, - InsertError>>, -> { +) -> Result, InsertError> { let mut source = Generic::from_fd_source(backend); source.set_interest(Interest::READABLE); diff --git a/src/backend/session/dbus/logind.rs b/src/backend/session/dbus/logind.rs index b613563..8319c74 100644 --- a/src/backend/session/dbus/logind.rs +++ b/src/backend/session/dbus/logind.rs @@ -268,7 +268,7 @@ impl LogindSessionImpl { //This session will never live again, but the user maybe has other sessions open //So lets just put it to sleep.. forever for signal in &mut *self.signals.borrow_mut() { - if let &mut Some(ref mut signal) = signal { + if let Some(ref mut signal) = signal { signal.pause(None); } } @@ -285,7 +285,7 @@ impl LogindSessionImpl { "Request of type \"{}\" to close device ({},{})", pause_type, major, minor ); for signal in &mut *self.signals.borrow_mut() { - if let &mut Some(ref mut signal) = signal { + if let Some(ref mut signal) = signal { signal.pause(Some((major, minor))); } } @@ -310,7 +310,7 @@ impl LogindSessionImpl { let fd = fd.ok_or(Error::UnexpectedMethodReturn)?.into_fd(); debug!(self.logger, "Reactivating device ({},{})", major, minor); for signal in &mut *self.signals.borrow_mut() { - if let &mut Some(ref mut signal) = signal { + if let Some(ref mut signal) = signal { signal.activate(Some((major, minor, Some(fd)))); } } @@ -356,7 +356,7 @@ impl Session for LogindSession { let fd = fd.ok_or(Error::UnexpectedMethodReturn)?.into_fd(); Ok(fd) } else { - return Err(Error::SessionLost); + Err(Error::SessionLost) } } @@ -376,7 +376,7 @@ impl Session for LogindSession { ) .map(|_| ()) } else { - return Err(Error::SessionLost); + Err(Error::SessionLost) } } @@ -404,7 +404,7 @@ impl Session for LogindSession { ) .map(|_| ()) } else { - return Err(Error::SessionLost); + Err(Error::SessionLost) } } } @@ -548,20 +548,30 @@ pub enum Error { /// Failed call to a dbus method #[error("Failed to call dbus method for service: {bus:?}, path: {path:?}, interface: {interface:?}, member: {member:?}")] FailedToSendDbusCall { + /// Name of the service bus: BusName<'static>, + /// Object path path: DbusPath<'static>, + /// Interface interface: Interface<'static>, + /// Method called member: Member<'static>, + /// DBus error #[source] source: dbus::Error, }, /// DBus method call failed #[error("Dbus message call failed for service: {bus:?}, path: {path:?}, interface: {interface:?}, member: {member:?}")] DbusCallFailed { + /// Name of the service bus: BusName<'static>, + /// Object path path: DbusPath<'static>, + /// Interface interface: Interface<'static>, + /// Method called member: Member<'static>, + /// DBus error #[source] source: dbus::Error, }, diff --git a/src/backend/session/direct.rs b/src/backend/session/direct.rs index 1188178..ffa7920 100644 --- a/src/backend/session/direct.rs +++ b/src/backend/session/direct.rs @@ -403,10 +403,9 @@ impl BoundDirectSession { pub fn unbind(self) -> DirectSessionNotifier { let BoundDirectSession { source, notifier } = self; source.remove(); - match Rc::try_unwrap(notifier) { - Ok(notifier) => notifier.into_inner(), - Err(_) => panic!("Notifier should have been freed from the event loop!"), - } + Rc::try_unwrap(notifier) + .map(RefCell::into_inner) + .unwrap_or_else(|_| panic!("Notifier should have been freed from the event loop!")) } } diff --git a/src/backend/udev.rs b/src/backend/udev.rs index 5001af6..a22b29d 100644 --- a/src/backend/udev.rs +++ b/src/backend/udev.rs @@ -90,6 +90,9 @@ impl Drop for UdevBackend { } } +/// calloop event source associated with the Udev backend +pub type UdevSource = Generic>>; + /// Binds a [`UdevBackend`] to a given [`EventLoop`](calloop::EventLoop). /// /// Allows the backend to receive kernel events and thus to drive the [`UdevHandler`]. @@ -97,7 +100,7 @@ impl Drop for UdevBackend { pub fn udev_backend_bind( udev: UdevBackend, handle: &LoopHandle, -) -> Result>>>, InsertError>>>> { +) -> Result>, InsertError>> { let mut source = Generic::from_fd_source(udev); source.set_interest(Interest::READABLE); diff --git a/src/wayland/compositor/handlers.rs b/src/wayland/compositor/handlers.rs index fdaff9e..df4adb3 100644 --- a/src/wayland/compositor/handlers.rs +++ b/src/wayland/compositor/handlers.rs @@ -7,8 +7,8 @@ use wayland_server::{ use super::{ tree::{Location, SurfaceData}, - CompositorToken, Damage, Rectangle, RectangleKind, RegionAttributes, Role, RoleType, SubsurfaceRole, - SurfaceEvent, + BufferAssignment, CompositorToken, Damage, Rectangle, RectangleKind, RegionAttributes, Role, RoleType, + SubsurfaceRole, SurfaceEvent, }; /* @@ -42,10 +42,12 @@ where * wl_surface */ +type SurfaceImplemFn = dyn FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken); + // Internal implementation data of surfaces pub(crate) struct SurfaceImplem { log: ::slog::Logger, - implem: Rc)>>, + implem: Rc>>, } impl SurfaceImplem { @@ -64,7 +66,15 @@ where fn receive_surface_request(&mut self, req: wl_surface::Request, surface: wl_surface::WlSurface) { match req { wl_surface::Request::Attach { buffer, x, y } => { - SurfaceData::::with_data(&surface, |d| d.buffer = Some(buffer.map(|b| (b, (x, y))))); + SurfaceData::::with_data(&surface, |d| { + d.buffer = Some(match buffer { + Some(buffer) => BufferAssignment::NewBuffer { + buffer, + delta: (x, y), + }, + None => BufferAssignment::Removed, + }) + }); } wl_surface::Request::Damage { x, y, width, height } => { SurfaceData::::with_data(&surface, |d| { @@ -128,10 +138,7 @@ where move |surface, req, _| implem.receive_surface_request(req, surface.deref().clone()) }); surface.assign_destructor(Filter::new(|surface, _, _| SurfaceData::::cleanup(&surface))); - surface - .as_ref() - .user_data() - .set_threadsafe(|| SurfaceData::::new()); + surface.as_ref().user_data().set_threadsafe(SurfaceData::::new); SurfaceData::::init(&surface); surface.deref().clone() } diff --git a/src/wayland/compositor/mod.rs b/src/wayland/compositor/mod.rs index 3cf066d..fe3fdbb 100644 --- a/src/wayland/compositor/mod.rs +++ b/src/wayland/compositor/mod.rs @@ -105,6 +105,19 @@ struct Marker { _r: ::std::marker::PhantomData, } +/// New buffer assignation for a surface +pub enum BufferAssignment { + /// The surface no longer has a buffer attached to it + Removed, + /// A new buffer has been attached + NewBuffer { + /// The buffer object + buffer: wl_buffer::WlBuffer, + /// location of the new buffer relative to the previous one + delta: (i32, i32), + }, +} + /// Data associated with a surface, aggregated by the handlers /// /// Most of the fields of this struct represent a double-buffered state, which @@ -116,16 +129,10 @@ struct Marker { pub struct SurfaceAttributes { /// Buffer defining the contents of the surface /// - /// The tuple represent the coordinates of this buffer - /// relative to the location of the current buffer. - /// - /// If set to `Some(None)`, it means the user specifically asked for the - /// surface to be unmapped. - /// /// You are free to set this field to `None` to avoid processing it several /// times. It'll be set to `Some(...)` if the user attaches a buffer (or `NULL`) to - /// the surface. - pub buffer: Option>, + /// the surface, and be left to `None` if the user does not attach anything. + pub buffer: Option, /// Scale of the contents of the buffer, for higher-resolution contents. /// /// If it matches the one of the output displaying this surface, no change diff --git a/src/wayland/compositor/roles.rs b/src/wayland/compositor/roles.rs index aadf5ef..83c718d 100644 --- a/src/wayland/compositor/roles.rs +++ b/src/wayland/compositor/roles.rs @@ -153,6 +153,10 @@ pub trait Role: RoleType { fn unset(&mut self) -> Result; } +/// The roles defining macro +/// +/// See the docs of the [`wayland::compositor::roles`](wayland/compositor/roles/index.html) module +/// for an explanation of its use. #[macro_export] macro_rules! define_roles( ($enum_name: ident) => { diff --git a/src/wayland/dmabuf/mod.rs b/src/wayland/dmabuf/mod.rs index 5f0c729..7bdd35b 100644 --- a/src/wayland/dmabuf/mod.rs +++ b/src/wayland/dmabuf/mod.rs @@ -103,6 +103,7 @@ pub struct Plane { } bitflags! { + /// Possible flags for a DMA buffer pub struct BufferFlags: u32 { /// The buffer content is Y-inverted const Y_INVERT = 1; @@ -219,9 +220,14 @@ where stride, modifier_hi, modifier_lo, - } => { - handler.add(&*params, fd, plane_idx, offset, stride, modifier_hi, modifier_lo) - } + } => handler.add( + &*params, + fd, + plane_idx, + offset, + stride, + ((modifier_hi as u64) << 32) + (modifier_lo as u64), + ), ParamsRequest::Create { width, height, @@ -269,8 +275,7 @@ impl ParamsHandler { plane_idx: u32, offset: u32, stride: u32, - modifier_hi: u32, - modifier_lo: u32, + modifier: u64, ) { // protocol checks: // Cannot reuse a params: @@ -304,7 +309,7 @@ impl ParamsHandler { plane_idx, offset, stride, - modifier: ((modifier_hi as u64) << 32) + (modifier_lo as u64), + modifier, }); } diff --git a/src/wayland/seat/mod.rs b/src/wayland/seat/mod.rs index 0eed676..1d8796a 100644 --- a/src/wayland/seat/mod.rs +++ b/src/wayland/seat/mod.rs @@ -361,7 +361,7 @@ where // same as pointer, should error but cannot } } - wl_seat::Request::GetTouch { id: _ } => { + wl_seat::Request::GetTouch { .. } => { // TODO } wl_seat::Request::Release => { diff --git a/src/wayland/shell/legacy/mod.rs b/src/wayland/shell/legacy/mod.rs index 010e93c..4c381b0 100644 --- a/src/wayland/shell/legacy/mod.rs +++ b/src/wayland/shell/legacy/mod.rs @@ -97,7 +97,7 @@ impl Clone for ShellSurface { Self { wl_surface: self.wl_surface.clone(), shell_surface: self.shell_surface.clone(), - token: self.token.clone(), + token: self.token, } } } diff --git a/src/wayland/shell/mod.rs b/src/wayland/shell/mod.rs index e34306c..114614e 100644 --- a/src/wayland/shell/mod.rs +++ b/src/wayland/shell/mod.rs @@ -1,2 +1,18 @@ +//! Handler utilities for the various shell protocols +//! +//! Wayland, via its different protocol extensions, supports different kind of +//! shells. Here a shell represent the logic associated to displaying windows and +//! arranging them on the screen. +//! +//! The shell protocols thus define what kind of interactions a client can have with +//! the compositor to properly display its contents on the screen. +//! +//! Smithay currently provides two of them: +//! +//! - The [`xdg`](xdg/index.hmtl) module provides handlers for the `xdg_shell` protocol, which is +//! the current standard for desktop apps +//! - The [`legacy`](legacy/index.html) module provides handlers for the `wl_shell` protocol, which +//! is now deprecated. You only need it if you want to support apps predating `xdg_shell`. + pub mod legacy; pub mod xdg; diff --git a/src/wayland/shell/xdg/mod.rs b/src/wayland/shell/xdg/mod.rs index 4b70cf8..77c7935 100644 --- a/src/wayland/shell/xdg/mod.rs +++ b/src/wayland/shell/xdg/mod.rs @@ -499,7 +499,7 @@ impl Clone for ToplevelSurface { Self { wl_surface: self.wl_surface.clone(), shell_surface: self.shell_surface.clone(), - token: self.token.clone(), + token: self.token, } } } diff --git a/src/xwayland/mod.rs b/src/xwayland/mod.rs index f4b91d0..28782c4 100644 --- a/src/xwayland/mod.rs +++ b/src/xwayland/mod.rs @@ -1,3 +1,18 @@ +//! XWayland utilities +//! +//! This module contains helpers to manage XWayland from your compositor, in order +//! to support running X11 apps. +//! +//! The starting point is the [`XWayland`](struct.XWayland.html) struct, which represents the +//! running `XWayland` instance. Dropping it will shutdown XWayland. +//! +//! You need to provide an implementation of the `XWindowManager` trait which gives you +//! access to the X11 WM connection and the `Client` associated with XWayland. You'll need +//! to treat XWayland (and all its X11 apps) as one special client, and play the role of +//! an X11 Window Manager. +//! +//! Smithay does not provide any helper for doing that yet, but it is planned. + mod x11_sockets; mod xserver; diff --git a/src/xwayland/xserver.rs b/src/xwayland/xserver.rs index 555d0bb..c6f9ce8 100644 --- a/src/xwayland/xserver.rs +++ b/src/xwayland/xserver.rs @@ -126,10 +126,12 @@ struct XWaylandInstance { child_pid: Option, } +type SourceMaker = dyn FnMut(Rc>>) -> Result, ()>; + // Inner implementation of the XWayland manager struct Inner { wm: WM, - source_maker: Box>>) -> Result, ()>>, + source_maker: Box>, wayland_display: Rc>, instance: Option, log: ::slog::Logger,