backend.session: migrate to wayland_rs-0.20
This commit is contained in:
parent
6dfcef1f49
commit
b80093ffda
|
@ -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" }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<DirectSessionNotifier>),
|
||||
Direct(Source<SignalEvent>),
|
||||
}
|
||||
|
||||
/// 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<BoundAutoSession, (IoError, AutoSessionNotifier)> {
|
||||
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<S: SessionObserver + 'static, A: AsSessionObserver<S>>(
|
||||
&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!()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Connection>,
|
||||
|
@ -62,6 +62,7 @@ pub struct LogindSession {
|
|||
}
|
||||
|
||||
/// `SessionNotifier` via the logind dbus interface
|
||||
#[derive(Clone)]
|
||||
pub struct LogindSessionNotifier {
|
||||
internal: Rc<LogindSessionImpl>,
|
||||
}
|
||||
|
@ -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<Vec<MessageItem>>,
|
||||
) -> Result<Message>
|
||||
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<S: SessionObserver + 'static, A: AsSessionObserver<S>>(
|
||||
&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<Watch>,
|
||||
sources: Vec<FdEventSource<Rc<LogindSessionImpl>>>,
|
||||
sources: Vec<Source<FdEvent>>,
|
||||
}
|
||||
|
||||
/// 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<BoundLogindSession, (IoError, LogindSessionNotifier)> {
|
||||
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<Vec<FdEventSource<Rc<LogindSessionImpl>>>, (IoError, _)>>()
|
||||
|
@ -492,13 +498,14 @@ impl Drop for LogindSessionNotifier {
|
|||
}
|
||||
}
|
||||
|
||||
fn fd_event_source_implementation() -> FdEventSourceImpl<Rc<LogindSessionImpl>> {
|
||||
FdEventSourceImpl {
|
||||
ready: |evlh, session, fd, interest| {
|
||||
let conn = session.conn.borrow();
|
||||
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 interest {
|
||||
match mask {
|
||||
x if x.contains(FdInterest::READ) && x.contains(FdInterest::WRITE) => {
|
||||
WatchEvent::Readable as u32 | WatchEvent::Writable as u32
|
||||
}
|
||||
|
@ -507,20 +514,24 @@ fn fd_event_source_implementation() -> FdEventSourceImpl<Rc<LogindSessionImpl>>
|
|||
_ => return,
|
||||
},
|
||||
);
|
||||
if let Err(err) = session.handle_signals(evlh, items) {
|
||||
error!(session.logger, "Error handling dbus signals: {}", err);
|
||||
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);
|
||||
}
|
||||
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 = session.conn.borrow();
|
||||
let conn = self.internal.conn.borrow();
|
||||
let items = conn.watch_handle(fd, WatchEvent::Error as u32);
|
||||
if let Err(err) = session.handle_signals(evlh, items) {
|
||||
if let Err(err) = self.internal.handle_signals(items) {
|
||||
error!(session.logger, "Error handling dbus signals: {}", err);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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("<stdin>"))))?;
|
||||
|
||||
let active = Arc::new(AtomicBool::new(true));
|
||||
|
@ -345,7 +349,8 @@ impl SessionNotifier for DirectSessionNotifier {
|
|||
type Id = Id;
|
||||
|
||||
fn register<S: SessionObserver + 'static, A: AsSessionObserver<S>>(
|
||||
&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<SignalEventSource<DirectSessionNotifier>, (IoError, DirectSessionNotifier)> {
|
||||
notifier: DirectSessionNotifier,
|
||||
token: &LoopToken,
|
||||
) -> ::std::result::Result<Source<SignalEvent>, (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! {
|
||||
|
|
|
@ -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<RawFd>)>);
|
||||
fn activate(&mut self, device: Option<(u32, u32, Option<RawFd>)>);
|
||||
}
|
||||
|
||||
impl Session for () {
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue