diff --git a/Cargo.toml b/Cargo.toml index de00edc..eace2cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/Smithay/smithay" [dependencies] wayland-server = "0.20.0" wayland-sys = "0.20.0" -nix = "0.9.0" +nix = "0.10.0" xkbcommon = "0.2.1" tempfile = "2.1.5" slog = { version = "2.1.1" } diff --git a/src/backend/mod.rs b/src/backend/mod.rs index de44d15..a0d970e 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -23,7 +23,7 @@ pub mod input; //pub mod drm; //#[cfg(feature = "backend_libinput")] //pub mod libinput; -//#[cfg(feature = "backend_session")] -//pub mod session; +#[cfg(feature = "backend_session")] +pub mod session; //#[cfg(feature = "backend_udev")] //pub mod udev; diff --git a/src/backend/session/auto.rs b/src/backend/session/auto.rs index 46bacde..59e4807 100644 --- a/src/backend/session/auto.rs +++ b/src/backend/session/auto.rs @@ -39,8 +39,9 @@ use std::io::Error as IoError; use std::os::unix::io::RawFd; use std::path::Path; use std::rc::Rc; -use wayland_server::EventLoopHandle; -use wayland_server::sources::{EventSource, SignalEventSource}; +use wayland_server::LoopToken; +use wayland_server::commons::downcast_impl; +use wayland_server::sources::{SignalEvent, Source}; /// `Session` using the best available inteface #[derive(Clone)] @@ -71,7 +72,7 @@ pub enum BoundAutoSession { #[cfg(feature = "backend_session_logind")] Logind(BoundLogindSession), /// Bound direct / tty session - Direct(SignalEventSource), + Direct(Source), } /// Id's used by the `AutoSessionNotifier` internally. @@ -153,13 +154,14 @@ impl AutoSession { /// If you don't use this function `AutoSessionNotifier` will not correctly tell you the /// session state and call it's `SessionObservers`. pub fn auto_session_bind( - notifier: AutoSessionNotifier, evlh: &mut EventLoopHandle + notifier: AutoSessionNotifier, + token: &LoopToken, ) -> ::std::result::Result { Ok(match notifier { #[cfg(feature = "backend_session_logind")] - AutoSessionNotifier::Logind(logind) => BoundAutoSession::Logind(logind_session_bind(logind, evlh) + AutoSessionNotifier::Logind(logind) => BoundAutoSession::Logind(logind_session_bind(logind, token) .map_err(|(error, notifier)| (error, AutoSessionNotifier::Logind(notifier)))?), - AutoSessionNotifier::Direct(direct) => BoundAutoSession::Direct(direct_session_bind(direct, evlh) + AutoSessionNotifier::Direct(direct) => BoundAutoSession::Direct(direct_session_bind(direct, token) .map_err(|(error, notifier)| (error, AutoSessionNotifier::Direct(notifier)))?), }) } @@ -210,7 +212,8 @@ impl SessionNotifier for AutoSessionNotifier { type Id = AutoId; fn register>( - &mut self, signal: &mut A + &mut self, + signal: &mut A, ) -> Self::Id { match self { #[cfg(feature = "backend_session_logind")] @@ -257,7 +260,9 @@ impl BoundAutoSession { match self { #[cfg(feature = "backend_session_logind")] BoundAutoSession::Logind(logind) => AutoSessionNotifier::Logind(logind.unbind()), - BoundAutoSession::Direct(source) => AutoSessionNotifier::Direct(source.remove()), + BoundAutoSession::Direct(source) => { + AutoSessionNotifier::Direct(*downcast_impl(source.remove()).unwrap_or_else(|_| unreachable!())) + } } } } diff --git a/src/backend/session/dbus/logind.rs b/src/backend/session/dbus/logind.rs index 54a3e4c..748f810 100644 --- a/src/backend/session/dbus/logind.rs +++ b/src/backend/session/dbus/logind.rs @@ -42,8 +42,8 @@ use std::path::Path; use std::rc::{Rc, Weak}; use std::sync::atomic::{AtomicBool, Ordering}; use systemd::login; -use wayland_server::EventLoopHandle; -use wayland_server::sources::{EventSource, FdEventSource, FdEventSourceImpl, FdInterest}; +use wayland_server::LoopToken; +use wayland_server::sources::{FdEvent, FdInterest, Source}; struct LogindSessionImpl { conn: RefCell, @@ -62,6 +62,7 @@ pub struct LogindSession { } /// `SessionNotifier` via the logind dbus interface +#[derive(Clone)] pub struct LogindSessionNotifier { internal: Rc, } @@ -186,7 +187,11 @@ impl LogindSessionNotifier { impl LogindSessionImpl { fn blocking_call<'d, 'p, 'i, 'm, D, P, I, M>( - conn: &Connection, destination: D, path: P, interface: I, method: M, + conn: &Connection, + destination: D, + path: P, + interface: I, + method: M, arguments: Option>, ) -> Result where @@ -230,7 +235,7 @@ impl LogindSessionImpl { } } - fn handle_signals(&self, evlh: &mut EventLoopHandle, signals: ConnectionItems) -> Result<()> { + fn handle_signals(&self, signals: ConnectionItems) -> Result<()> { for item in signals { let message = if let ConnectionItem::Signal(ref s) = item { s @@ -246,7 +251,7 @@ impl LogindSessionImpl { //So lets just put it to sleep.. forever for signal in &mut *self.signals.borrow_mut() { if let &mut Some(ref mut signal) = signal { - signal.pause(evlh, None); + signal.pause(None); } } self.active.store(false, Ordering::SeqCst); @@ -263,7 +268,7 @@ impl LogindSessionImpl { ); for signal in &mut *self.signals.borrow_mut() { if let &mut Some(ref mut signal) = signal { - signal.pause(evlh, Some((major, minor))); + signal.pause(Some((major, minor))); } } // the other possible types are "force" or "gone" (unplugged), @@ -289,7 +294,7 @@ impl LogindSessionImpl { debug!(self.logger, "Reactivating device ({},{})", major, minor); for signal in &mut *self.signals.borrow_mut() { if let &mut Some(ref mut signal) = signal { - signal.activate(evlh, Some((major, minor, Some(fd)))); + signal.activate(Some((major, minor, Some(fd)))); } } } @@ -393,7 +398,8 @@ impl SessionNotifier for LogindSessionNotifier { type Id = Id; fn register>( - &mut self, signal: &mut A + &mut self, + signal: &mut A, ) -> Self::Id { self.internal .signals @@ -422,7 +428,7 @@ impl SessionNotifier for LogindSessionNotifier { pub struct BoundLogindSession { notifier: LogindSessionNotifier, _watches: Vec, - sources: Vec>>, + sources: Vec>, } /// Bind a `LogindSessionNotifier` to an `EventLoop`. @@ -431,7 +437,8 @@ pub struct BoundLogindSession { /// If you don't use this function `LogindSessionNotifier` will not correctly tell you the logind /// session state and call it's `SessionObservers`. pub fn logind_session_bind( - notifier: LogindSessionNotifier, evlh: &mut EventLoopHandle + notifier: LogindSessionNotifier, + token: &LoopToken, ) -> ::std::result::Result { let watches = notifier.internal.conn.borrow().watch_fds(); @@ -443,11 +450,10 @@ pub fn logind_session_bind( let mut interest = FdInterest::empty(); interest.set(FdInterest::READ, watch.readable()); interest.set(FdInterest::WRITE, watch.writable()); - evlh.add_fd_event_source( + token.add_fd_event_source( watch.fd(), - fd_event_source_implementation(), - notifier.internal.clone(), interest, + notifier.clone(), ) }) .collect::<::std::result::Result>>, (IoError, _)>>() @@ -492,35 +498,40 @@ impl Drop for LogindSessionNotifier { } } -fn fd_event_source_implementation() -> FdEventSourceImpl> { - FdEventSourceImpl { - ready: |evlh, session, fd, interest| { - let conn = session.conn.borrow(); - let items = conn.watch_handle( - fd, - match interest { - x if x.contains(FdInterest::READ) && x.contains(FdInterest::WRITE) => { - WatchEvent::Readable as u32 | WatchEvent::Writable as u32 - } - x if x.contains(FdInterest::READ) => WatchEvent::Readable as u32, - x if x.contains(FdInterest::WRITE) => WatchEvent::Writable as u32, - _ => return, - }, - ); - if let Err(err) = session.handle_signals(evlh, items) { - error!(session.logger, "Error handling dbus signals: {}", err); +impl Implementation<(), FdEvent> for LogindSessionNotifier { + fn receive(&mut self, event: FdEvent, (): ()) { + match event { + FdEvent::Ready { fd, mask } => { + let conn = self.internal.conn.borrow(); + let items = conn.watch_handle( + fd, + match mask { + x if x.contains(FdInterest::READ) && x.contains(FdInterest::WRITE) => { + WatchEvent::Readable as u32 | WatchEvent::Writable as u32 + } + x if x.contains(FdInterest::READ) => WatchEvent::Readable as u32, + x if x.contains(FdInterest::WRITE) => WatchEvent::Writable as u32, + _ => return, + }, + ); + if let Err(err) = self.internal.handle_signals(items) { + error!(self.internal.logger, "Error handling dbus signals: {}", err); + } } - }, - error: |evlh, session, fd, error| { - warn!(session.logger, "Error on dbus connection: {:?}", error); - // handle the remaining messages, they might contain the SessionRemoved event - // in case the server did close the connection. - let conn = session.conn.borrow(); - let items = conn.watch_handle(fd, WatchEvent::Error as u32); - if let Err(err) = session.handle_signals(evlh, items) { - error!(session.logger, "Error handling dbus signals: {}", err); + FdEvent::Error { fd, error } => { + warn!( + self.internal.logger, + "Error on dbus connection: {:?}", error + ); + // handle the remaining messages, they might contain the SessionRemoved event + // in case the server did close the connection. + let conn = self.internal.conn.borrow(); + let items = conn.watch_handle(fd, WatchEvent::Error as u32); + if let Err(err) = self.internal.handle_signals(items) { + error!(session.logger, "Error handling dbus signals: {}", err); + } } - }, + } } } diff --git a/src/backend/session/direct.rs b/src/backend/session/direct.rs index eaeded8..f9a5c71 100644 --- a/src/backend/session/direct.rs +++ b/src/backend/session/direct.rs @@ -59,8 +59,9 @@ use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; #[cfg(feature = "backend_session_udev")] use udev::Context; -use wayland_server::EventLoopHandle; -use wayland_server::sources::SignalEventSource; +use wayland_server::LoopToken; +use wayland_server::commons::Implementation; +use wayland_server::sources::{SignalEvent, Source}; #[allow(dead_code)] mod tty { @@ -171,8 +172,11 @@ impl DirectSession { .new(o!("smithay_module" => "backend_session", "session_type" => "direct/vt")); let fd = tty.map(|path| { - open(path, fcntl::O_RDWR | fcntl::O_CLOEXEC, Mode::empty()) - .chain_err(|| ErrorKind::FailedToOpenTTY(String::from(path.to_string_lossy()))) + open( + path, + fcntl::OFlag::O_RDWR | fcntl::OFlag::O_CLOEXEC, + Mode::empty(), + ).chain_err(|| ErrorKind::FailedToOpenTTY(String::from(path.to_string_lossy()))) }).unwrap_or(dup(0 /*stdin*/).chain_err(|| ErrorKind::FailedToOpenTTY(String::from(""))))?; let active = Arc::new(AtomicBool::new(true)); @@ -345,7 +349,8 @@ impl SessionNotifier for DirectSessionNotifier { type Id = Id; fn register>( - &mut self, signal: &mut A + &mut self, + signal: &mut A, ) -> Self::Id { self.signals.push(Some(Box::new(signal.observer()))); Id(self.signals.len() - 1) @@ -362,47 +367,48 @@ impl SessionNotifier for DirectSessionNotifier { } } +impl Implementation<(), SignalEvent> for DirectSessionNotifier { + fn receive(&mut self, _signal: SignalEvent, (): ()) { + if self.is_active() { + info!(self.logger, "Session shall become inactive."); + for signal in &mut self.signals { + if let &mut Some(ref mut signal) = signal { + signal.pause(None); + } + } + self.active.store(false, Ordering::SeqCst); + unsafe { + tty::vt_rel_disp(self.tty, 1).expect("Unable to release tty lock"); + } + debug!(self.logger, "Session is now inactive"); + } else { + debug!(self.logger, "Session will become active again"); + unsafe { + tty::vt_rel_disp(self.tty, tty::VT_ACKACQ).expect("Unable to acquire tty lock"); + } + for signal in &mut self.signals { + if let &mut Some(ref mut signal) = signal { + signal.activate(None); + } + } + self.active.store(true, Ordering::SeqCst); + info!(self.logger, "Session is now active again"); + } + } +} + /// Bind a `DirectSessionNotifier` to an `EventLoop`. /// /// Allows the `DirectSessionNotifier` to listen for incoming signals signalling the session state. /// If you don't use this function `DirectSessionNotifier` will not correctly tell you the current /// session state and call it's `SessionObservers`. pub fn direct_session_bind( - notifier: DirectSessionNotifier, evlh: &mut EventLoopHandle -) -> ::std::result::Result, (IoError, DirectSessionNotifier)> { + notifier: DirectSessionNotifier, + token: &LoopToken, +) -> ::std::result::Result, (IoError, DirectSessionNotifier)> { let signal = notifier.signal; - evlh.add_signal_event_source( - |evlh, notifier, _| { - if notifier.is_active() { - info!(notifier.logger, "Session shall become inactive"); - for signal in &mut notifier.signals { - if let &mut Some(ref mut signal) = signal { - signal.pause(evlh, None); - } - } - notifier.active.store(false, Ordering::SeqCst); - unsafe { - tty::vt_rel_disp(notifier.tty, 1).expect("Unable to release tty lock"); - } - debug!(notifier.logger, "Session is now inactive"); - } else { - debug!(notifier.logger, "Session will become active again"); - unsafe { - tty::vt_rel_disp(notifier.tty, tty::VT_ACKACQ).expect("Unable to acquire tty lock"); - } - for signal in &mut notifier.signals { - if let &mut Some(ref mut signal) = signal { - signal.activate(evlh, None); - } - } - notifier.active.store(true, Ordering::SeqCst); - info!(notifier.logger, "Session is now active again"); - } - }, - notifier, - signal, - ) + token.add_signal_event_source(signal, notifier) } error_chain! { diff --git a/src/backend/session/mod.rs b/src/backend/session/mod.rs index a11c6d3..de8b430 100644 --- a/src/backend/session/mod.rs +++ b/src/backend/session/mod.rs @@ -16,7 +16,6 @@ use std::os::unix::io::RawFd; use std::path::Path; use std::rc::Rc; use std::sync::{Arc, Mutex}; -use wayland_server::EventLoopHandle; /// General session interface. /// @@ -88,7 +87,7 @@ pub trait SessionObserver { /// If only a specific device shall be closed a device number in the form of /// (major, minor) is provided. All observers not using the specified device should /// ignore the signal in that case. - fn pause(&mut self, evlh: &mut EventLoopHandle, device: Option<(u32, u32)>); + fn pause(&mut self, device: Option<(u32, u32)>); /// Session/Device got active again /// /// If only a specific device shall be activated again a device number in the form of @@ -96,7 +95,7 @@ pub trait SessionObserver { /// the currently open file descriptor of the device with a new one. In that case the old one /// should not be used anymore and be closed. All observers not using the specified device should /// ignore the signal in that case. - fn activate(&mut self, evlh: &mut EventLoopHandle, device: Option<(u32, u32, Option)>); + fn activate(&mut self, device: Option<(u32, u32, Option)>); } impl Session for () { diff --git a/src/wayland/shm/pool.rs b/src/wayland/shm/pool.rs index b70442a..2bbcaab 100644 --- a/src/wayland/shm/pool.rs +++ b/src/wayland/shm/pool.rs @@ -161,8 +161,8 @@ unsafe fn map(fd: RawFd, size: usize) -> Result<*mut u8, ()> { let ret = mman::mmap( ptr::null_mut(), size, - mman::PROT_READ, - mman::MAP_SHARED, + mman::ProtFlags::PROT_READ, + mman::MapFlags::MAP_SHARED, fd, 0, ); @@ -179,8 +179,8 @@ unsafe fn nullify_map(ptr: *mut u8, size: usize) -> Result<(), ()> { let ret = mman::mmap( ptr as *mut _, size, - mman::PROT_READ, - mman::MAP_ANONYMOUS | mman::MAP_PRIVATE | mman::MAP_FIXED, + mman::ProtFlags::PROT_READ, + mman::MapFlags::MAP_ANONYMOUS | mman::MapFlags::MAP_PRIVATE | mman::MapFlags::MAP_FIXED, -1, 0, ); @@ -191,7 +191,7 @@ unsafe fn place_sigbus_handler() { // create our sigbus handler let action = SigAction::new( SigHandler::SigAction(sigbus_handler), - signal::SA_NODEFER, + signal::SaFlags::SA_NODEFER, signal::SigSet::empty(), ); match signal::sigaction(Signal::SIGBUS, &action) {