cargo fmt
This commit is contained in:
parent
605895e30f
commit
454f874284
|
@ -2,10 +2,11 @@ use glium;
|
||||||
use glium::index::PrimitiveType;
|
use glium::index::PrimitiveType;
|
||||||
use glium::texture::{MipmapsOption, Texture2d, UncompressedFloatFormat};
|
use glium::texture::{MipmapsOption, Texture2d, UncompressedFloatFormat};
|
||||||
use glium::{Frame, GlObject, Surface};
|
use glium::{Frame, GlObject, Surface};
|
||||||
use smithay::backend::graphics::egl::EGLGraphicsBackend;
|
|
||||||
use smithay::backend::graphics::egl::error::Result as EGLResult;
|
use smithay::backend::graphics::egl::error::Result as EGLResult;
|
||||||
use smithay::backend::graphics::egl::wayland::{BufferAccessError, EGLDisplay, EGLImages,
|
use smithay::backend::graphics::egl::wayland::{
|
||||||
EGLWaylandExtensions, Format};
|
BufferAccessError, EGLDisplay, EGLImages, EGLWaylandExtensions, Format,
|
||||||
|
};
|
||||||
|
use smithay::backend::graphics::egl::EGLGraphicsBackend;
|
||||||
use smithay::backend::graphics::glium::GliumGraphicsBackend;
|
use smithay::backend::graphics::glium::GliumGraphicsBackend;
|
||||||
use smithay::wayland::compositor::roles::Role;
|
use smithay::wayland::compositor::roles::Role;
|
||||||
use smithay::wayland::compositor::{SubsurfaceRole, TraversalAction};
|
use smithay::wayland::compositor::{SubsurfaceRole, TraversalAction};
|
||||||
|
@ -199,8 +200,7 @@ impl<F: EGLGraphicsBackend + 'static> GliumDrawer<F> {
|
||||||
blend: blending,
|
blend: blending,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
).unwrap();
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -282,8 +282,7 @@ impl<F: EGLGraphicsBackend + 'static> GliumDrawer<F> {
|
||||||
TraversalAction::SkipChildren
|
TraversalAction::SkipChildren
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
).unwrap();
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use slog::Logger;
|
use slog::Logger;
|
||||||
|
|
||||||
|
use smithay::backend::input::{
|
||||||
|
self, Event, InputBackend, InputHandler, KeyState, KeyboardKeyEvent, PointerAxisEvent,
|
||||||
|
PointerButtonEvent, PointerMotionAbsoluteEvent, PointerMotionEvent,
|
||||||
|
};
|
||||||
#[cfg(feature = "udev")]
|
#[cfg(feature = "udev")]
|
||||||
use smithay::backend::session::auto::AutoSession;
|
use smithay::backend::session::auto::AutoSession;
|
||||||
use smithay::backend::input::{self, Event, InputBackend, InputHandler, KeyState, KeyboardKeyEvent,
|
|
||||||
PointerAxisEvent, PointerButtonEvent, PointerMotionAbsoluteEvent,
|
|
||||||
PointerMotionEvent};
|
|
||||||
use smithay::wayland::seat::{keysyms as xkb, KeyboardHandle, Keysym, ModifiersState, PointerHandle};
|
use smithay::wayland::seat::{keysyms as xkb, KeyboardHandle, Keysym, ModifiersState, PointerHandle};
|
||||||
use smithay::wayland_server::protocol::wl_pointer;
|
use smithay::wayland_server::protocol::wl_pointer;
|
||||||
|
|
||||||
|
@ -160,7 +161,8 @@ impl<B: InputBackend> InputHandler<B> for AnvilInputHandler {
|
||||||
// this event is never generated by winit so self.screen_size is relevant
|
// this event is never generated by winit so self.screen_size is relevant
|
||||||
location.0 = (location.0).max(0.0).min(self.screen_size.0 as f64);
|
location.0 = (location.0).max(0.0).min(self.screen_size.0 as f64);
|
||||||
location.1 = (location.1).max(0.0).min(self.screen_size.1 as f64);
|
location.1 = (location.1).max(0.0).min(self.screen_size.1 as f64);
|
||||||
let under = self.window_map
|
let under = self
|
||||||
|
.window_map
|
||||||
.borrow()
|
.borrow()
|
||||||
.get_surface_under((location.0, location.1));
|
.get_surface_under((location.0, location.1));
|
||||||
self.pointer.motion(
|
self.pointer.motion(
|
||||||
|
@ -191,9 +193,7 @@ impl<B: InputBackend> InputHandler<B> for AnvilInputHandler {
|
||||||
};
|
};
|
||||||
*self.pointer_location.borrow_mut() = (x, y);
|
*self.pointer_location.borrow_mut() = (x, y);
|
||||||
let serial = self.next_serial();
|
let serial = self.next_serial();
|
||||||
let under = self.window_map
|
let under = self.window_map.borrow().get_surface_under((x as f64, y as f64));
|
||||||
.borrow()
|
|
||||||
.get_surface_under((x as f64, y as f64));
|
|
||||||
self.pointer.motion(
|
self.pointer.motion(
|
||||||
under.as_ref().map(|&(ref s, (x, y))| (s, x, y)),
|
under.as_ref().map(|&(ref s, (x, y))| (s, x, y)),
|
||||||
serial,
|
serial,
|
||||||
|
@ -212,7 +212,8 @@ impl<B: InputBackend> InputHandler<B> for AnvilInputHandler {
|
||||||
let state = match evt.state() {
|
let state = match evt.state() {
|
||||||
input::MouseButtonState::Pressed => {
|
input::MouseButtonState::Pressed => {
|
||||||
// change the keyboard focus
|
// change the keyboard focus
|
||||||
let under = self.window_map
|
let under = self
|
||||||
|
.window_map
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.get_surface_and_bring_to_top(*self.pointer_location.borrow());
|
.get_surface_and_bring_to_top(*self.pointer_location.borrow());
|
||||||
self.keyboard
|
self.keyboard
|
||||||
|
@ -230,9 +231,11 @@ impl<B: InputBackend> InputHandler<B> for AnvilInputHandler {
|
||||||
input::AxisSource::Finger => wl_pointer::AxisSource::Finger,
|
input::AxisSource::Finger => wl_pointer::AxisSource::Finger,
|
||||||
input::AxisSource::Wheel | input::AxisSource::WheelTilt => wl_pointer::AxisSource::Wheel,
|
input::AxisSource::Wheel | input::AxisSource::WheelTilt => wl_pointer::AxisSource::Wheel,
|
||||||
};
|
};
|
||||||
let horizontal_amount = evt.amount(&input::Axis::Horizontal)
|
let horizontal_amount = evt
|
||||||
|
.amount(&input::Axis::Horizontal)
|
||||||
.unwrap_or_else(|| evt.amount_discrete(&input::Axis::Horizontal).unwrap() * 3.0);
|
.unwrap_or_else(|| evt.amount_discrete(&input::Axis::Horizontal).unwrap() * 3.0);
|
||||||
let vertical_amount = evt.amount(&input::Axis::Vertical)
|
let vertical_amount = evt
|
||||||
|
.amount(&input::Axis::Vertical)
|
||||||
.unwrap_or_else(|| evt.amount_discrete(&input::Axis::Vertical).unwrap() * 3.0);
|
.unwrap_or_else(|| evt.amount_discrete(&input::Axis::Vertical).unwrap() * 3.0);
|
||||||
let horizontal_amount_discrete = evt.amount_discrete(&input::Axis::Horizontal);
|
let horizontal_amount_discrete = evt.amount_discrete(&input::Axis::Horizontal);
|
||||||
let vertical_amount_discrete = evt.amount_discrete(&input::Axis::Vertical);
|
let vertical_amount_discrete = evt.amount_discrete(&input::Axis::Vertical);
|
||||||
|
@ -241,11 +244,7 @@ impl<B: InputBackend> InputHandler<B> for AnvilInputHandler {
|
||||||
let mut event = self.pointer.axis();
|
let mut event = self.pointer.axis();
|
||||||
event.source(source);
|
event.source(source);
|
||||||
if horizontal_amount != 0.0 {
|
if horizontal_amount != 0.0 {
|
||||||
event.value(
|
event.value(wl_pointer::Axis::HorizontalScroll, horizontal_amount, evt.time());
|
||||||
wl_pointer::Axis::HorizontalScroll,
|
|
||||||
horizontal_amount,
|
|
||||||
evt.time(),
|
|
||||||
);
|
|
||||||
if let Some(discrete) = horizontal_amount_discrete {
|
if let Some(discrete) = horizontal_amount_discrete {
|
||||||
event.discrete(wl_pointer::Axis::HorizontalScroll, discrete as i32);
|
event.discrete(wl_pointer::Axis::HorizontalScroll, discrete as i32);
|
||||||
}
|
}
|
||||||
|
@ -253,11 +252,7 @@ impl<B: InputBackend> InputHandler<B> for AnvilInputHandler {
|
||||||
event.stop(wl_pointer::Axis::HorizontalScroll, evt.time());
|
event.stop(wl_pointer::Axis::HorizontalScroll, evt.time());
|
||||||
}
|
}
|
||||||
if vertical_amount != 0.0 {
|
if vertical_amount != 0.0 {
|
||||||
event.value(
|
event.value(wl_pointer::Axis::VerticalScroll, vertical_amount, evt.time());
|
||||||
wl_pointer::Axis::VerticalScroll,
|
|
||||||
vertical_amount,
|
|
||||||
evt.time(),
|
|
||||||
);
|
|
||||||
if let Some(discrete) = vertical_amount_discrete {
|
if let Some(discrete) = vertical_amount_discrete {
|
||||||
event.discrete(wl_pointer::Axis::VerticalScroll, discrete as i32);
|
event.discrete(wl_pointer::Axis::VerticalScroll, discrete as i32);
|
||||||
}
|
}
|
||||||
|
@ -304,10 +299,11 @@ enum KeyAction {
|
||||||
|
|
||||||
fn process_keyboard_shortcut(modifiers: &ModifiersState, keysym: Keysym) -> KeyAction {
|
fn process_keyboard_shortcut(modifiers: &ModifiersState, keysym: Keysym) -> KeyAction {
|
||||||
if modifiers.ctrl && modifiers.alt && keysym == xkb::KEY_BackSpace
|
if modifiers.ctrl && modifiers.alt && keysym == xkb::KEY_BackSpace
|
||||||
|| modifiers.logo && keysym == xkb::KEY_q {
|
|| modifiers.logo && keysym == xkb::KEY_q
|
||||||
// ctrl+alt+backspace = quit
|
{
|
||||||
// logo + q = quit
|
// ctrl+alt+backspace = quit
|
||||||
KeyAction::Quit
|
// logo + q = quit
|
||||||
|
KeyAction::Quit
|
||||||
} else if keysym >= xkb::KEY_XF86Switch_VT_1 && keysym <= xkb::KEY_XF86Switch_VT_12 {
|
} else if keysym >= xkb::KEY_XF86Switch_VT_1 && keysym <= xkb::KEY_XF86Switch_VT_12 {
|
||||||
// VTSwicth
|
// VTSwicth
|
||||||
KeyAction::VtSwitch((keysym - xkb::KEY_XF86Switch_VT_1 + 1) as i32)
|
KeyAction::VtSwitch((keysym - xkb::KEY_XF86Switch_VT_1 + 1) as i32)
|
||||||
|
|
|
@ -10,8 +10,8 @@ extern crate smithay;
|
||||||
extern crate xkbcommon;
|
extern crate xkbcommon;
|
||||||
|
|
||||||
use slog::Drain;
|
use slog::Drain;
|
||||||
use smithay::wayland_server::Display;
|
|
||||||
use smithay::wayland_server::calloop::EventLoop;
|
use smithay::wayland_server::calloop::EventLoop;
|
||||||
|
use smithay::wayland_server::Display;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod shaders;
|
mod shaders;
|
||||||
|
|
|
@ -5,18 +5,18 @@ use std::os::unix::io::RawFd;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use smithay::drm::Device as BasicDevice;
|
use smithay::backend::drm::{drm_device_bind, DrmBackend, DrmDevice, DrmHandler};
|
||||||
use smithay::drm::control::{Device as ControlDevice, ResourceInfo};
|
use smithay::backend::graphics::egl::wayland::EGLWaylandExtensions;
|
||||||
use smithay::drm::control::connector::{Info as ConnectorInfo, State as ConnectorState};
|
use smithay::drm::control::connector::{Info as ConnectorInfo, State as ConnectorState};
|
||||||
use smithay::drm::control::crtc;
|
use smithay::drm::control::crtc;
|
||||||
use smithay::drm::control::encoder::Info as EncoderInfo;
|
use smithay::drm::control::encoder::Info as EncoderInfo;
|
||||||
|
use smithay::drm::control::{Device as ControlDevice, ResourceInfo};
|
||||||
use smithay::drm::result::Error as DrmError;
|
use smithay::drm::result::Error as DrmError;
|
||||||
use smithay::backend::drm::{drm_device_bind, DrmBackend, DrmDevice, DrmHandler};
|
use smithay::drm::Device as BasicDevice;
|
||||||
use smithay::backend::graphics::egl::wayland::EGLWaylandExtensions;
|
|
||||||
use smithay::wayland::compositor::CompositorToken;
|
use smithay::wayland::compositor::CompositorToken;
|
||||||
use smithay::wayland::shm::init_shm_global;
|
use smithay::wayland::shm::init_shm_global;
|
||||||
use smithay::wayland_server::Display;
|
|
||||||
use smithay::wayland_server::calloop::EventLoop;
|
use smithay::wayland_server::calloop::EventLoop;
|
||||||
|
use smithay::wayland_server::Display;
|
||||||
|
|
||||||
use glium::Surface;
|
use glium::Surface;
|
||||||
use slog::Logger;
|
use slog::Logger;
|
||||||
|
@ -44,10 +44,8 @@ pub fn run_raw_drm(mut display: Display, mut event_loop: EventLoop<()>, log: Log
|
||||||
let mut options = OpenOptions::new();
|
let mut options = OpenOptions::new();
|
||||||
options.read(true);
|
options.read(true);
|
||||||
options.write(true);
|
options.write(true);
|
||||||
let mut device = DrmDevice::new(
|
let mut device =
|
||||||
Card(options.clone().open("/dev/dri/card0").unwrap()),
|
DrmDevice::new(Card(options.clone().open("/dev/dri/card0").unwrap()), log.clone()).unwrap();
|
||||||
log.clone(),
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
// Get a set of all modesetting resource handles (excluding planes):
|
// Get a set of all modesetting resource handles (excluding planes):
|
||||||
let res_handles = device.resource_handles().unwrap();
|
let res_handles = device.resource_handles().unwrap();
|
||||||
|
@ -124,10 +122,12 @@ pub fn run_raw_drm(mut display: Display, mut event_loop: EventLoop<()>, log: Log
|
||||||
logger: log,
|
logger: log,
|
||||||
},
|
},
|
||||||
).map_err(|(err, _)| err)
|
).map_err(|(err, _)| err)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
event_loop.dispatch(Some(::std::time::Duration::from_millis(16)), &mut ()).unwrap();
|
event_loop
|
||||||
|
.dispatch(Some(::std::time::Duration::from_millis(16)), &mut ())
|
||||||
|
.unwrap();
|
||||||
display.flush_clients();
|
display.flush_clients();
|
||||||
|
|
||||||
window_map.borrow_mut().refresh();
|
window_map.borrow_mut().refresh();
|
||||||
|
@ -149,11 +149,8 @@ impl DrmHandler<Card> for DrmHandlerImpl {
|
||||||
_frame: u32,
|
_frame: u32,
|
||||||
_duration: Duration,
|
_duration: Duration,
|
||||||
) {
|
) {
|
||||||
self.drawer.draw_windows(
|
self.drawer
|
||||||
&*self.window_map.borrow(),
|
.draw_windows(&*self.window_map.borrow(), self.compositor_token, &self.logger);
|
||||||
self.compositor_token,
|
|
||||||
&self.logger,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error(&mut self, _device: &mut DrmDevice<Card>, error: DrmError) {
|
fn error(&mut self, _device: &mut DrmDevice<Card>, error: DrmError) {
|
||||||
|
|
|
@ -5,10 +5,13 @@ use std::sync::{Arc, Mutex};
|
||||||
use rand;
|
use rand;
|
||||||
|
|
||||||
use smithay::wayland::compositor::{compositor_init, CompositorToken, SurfaceAttributes, SurfaceEvent};
|
use smithay::wayland::compositor::{compositor_init, CompositorToken, SurfaceAttributes, SurfaceEvent};
|
||||||
use smithay::wayland::shell::legacy::{wl_shell_init, ShellRequest, ShellState as WlShellState,
|
use smithay::wayland::shell::legacy::{
|
||||||
ShellSurfaceKind, ShellSurfaceRole};
|
wl_shell_init, ShellRequest, ShellState as WlShellState, ShellSurfaceKind, ShellSurfaceRole,
|
||||||
use smithay::wayland::shell::xdg::{xdg_shell_init, PopupConfigure, ShellState as XdgShellState,
|
};
|
||||||
ToplevelConfigure, XdgRequest, XdgSurfaceRole};
|
use smithay::wayland::shell::xdg::{
|
||||||
|
xdg_shell_init, PopupConfigure, ShellState as XdgShellState, ToplevelConfigure, XdgRequest,
|
||||||
|
XdgSurfaceRole,
|
||||||
|
};
|
||||||
use smithay::wayland_server::protocol::{wl_buffer, wl_callback, wl_shell_surface, wl_surface};
|
use smithay::wayland_server::protocol::{wl_buffer, wl_callback, wl_shell_surface, wl_surface};
|
||||||
use smithay::wayland_server::{Display, Resource};
|
use smithay::wayland_server::{Display, Resource};
|
||||||
|
|
||||||
|
@ -85,11 +88,12 @@ pub fn init_shell(
|
||||||
let (wl_shell_state, _) = wl_shell_init(
|
let (wl_shell_state, _) = wl_shell_init(
|
||||||
display,
|
display,
|
||||||
compositor_token,
|
compositor_token,
|
||||||
move |req: ShellRequest<_, _, ()>|
|
move |req: ShellRequest<_, _, ()>| {
|
||||||
if let ShellRequest::SetKind {
|
if let ShellRequest::SetKind {
|
||||||
surface,
|
surface,
|
||||||
kind: ShellSurfaceKind::Toplevel,
|
kind: ShellSurfaceKind::Toplevel,
|
||||||
} = req {
|
} = req
|
||||||
|
{
|
||||||
// place the window at a random location in the [0;300]x[0;300] square
|
// place the window at a random location in the [0;300]x[0;300] square
|
||||||
use rand::distributions::{IndependentSample, Range};
|
use rand::distributions::{IndependentSample, Range};
|
||||||
let range = Range::new(0, 300);
|
let range = Range::new(0, 300);
|
||||||
|
@ -100,7 +104,8 @@ pub fn init_shell(
|
||||||
shell_window_map
|
shell_window_map
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.insert(SurfaceKind::Wl(surface), (x, y));
|
.insert(SurfaceKind::Wl(surface), (x, y));
|
||||||
},
|
}
|
||||||
|
},
|
||||||
log.clone(),
|
log.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@ use std::collections::HashMap;
|
||||||
use std::io::Error as IoError;
|
use std::io::Error as IoError;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use glium::Surface;
|
use glium::Surface;
|
||||||
|
@ -13,31 +13,31 @@ use smithay::image::{ImageBuffer, Rgba};
|
||||||
|
|
||||||
use slog::Logger;
|
use slog::Logger;
|
||||||
|
|
||||||
use smithay::drm::control::{Device as ControlDevice, ResourceInfo};
|
use smithay::backend::drm::{DevPath, DrmBackend, DrmDevice, DrmHandler};
|
||||||
|
use smithay::backend::graphics::egl::wayland::{EGLDisplay, EGLWaylandExtensions};
|
||||||
|
use smithay::backend::graphics::GraphicsBackend;
|
||||||
|
use smithay::backend::input::InputBackend;
|
||||||
|
use smithay::backend::libinput::{libinput_bind, LibinputInputBackend, LibinputSessionInterface};
|
||||||
|
use smithay::backend::session::auto::{auto_session_bind, AutoSession};
|
||||||
|
use smithay::backend::session::{Session, SessionNotifier};
|
||||||
|
use smithay::backend::udev::{primary_gpu, udev_backend_bind, SessionFdDrmDevice, UdevBackend, UdevHandler};
|
||||||
use smithay::drm::control::connector::{Info as ConnectorInfo, State as ConnectorState};
|
use smithay::drm::control::connector::{Info as ConnectorInfo, State as ConnectorState};
|
||||||
use smithay::drm::control::crtc;
|
use smithay::drm::control::crtc;
|
||||||
use smithay::drm::control::encoder::Info as EncoderInfo;
|
use smithay::drm::control::encoder::Info as EncoderInfo;
|
||||||
|
use smithay::drm::control::{Device as ControlDevice, ResourceInfo};
|
||||||
use smithay::drm::result::Error as DrmError;
|
use smithay::drm::result::Error as DrmError;
|
||||||
use smithay::backend::drm::{DevPath, DrmBackend, DrmDevice, DrmHandler};
|
use smithay::input::Libinput;
|
||||||
use smithay::backend::graphics::GraphicsBackend;
|
|
||||||
use smithay::backend::graphics::egl::wayland::{EGLDisplay, EGLWaylandExtensions};
|
|
||||||
use smithay::backend::input::InputBackend;
|
|
||||||
use smithay::backend::libinput::{libinput_bind, LibinputInputBackend, LibinputSessionInterface};
|
|
||||||
use smithay::backend::session::{Session, SessionNotifier};
|
|
||||||
use smithay::backend::session::auto::{auto_session_bind, AutoSession};
|
|
||||||
use smithay::backend::udev::{primary_gpu, udev_backend_bind, SessionFdDrmDevice, UdevBackend, UdevHandler};
|
|
||||||
use smithay::wayland::compositor::CompositorToken;
|
use smithay::wayland::compositor::CompositorToken;
|
||||||
use smithay::wayland::output::{Mode, Output, PhysicalProperties};
|
use smithay::wayland::output::{Mode, Output, PhysicalProperties};
|
||||||
use smithay::wayland::seat::Seat;
|
use smithay::wayland::seat::Seat;
|
||||||
use smithay::wayland::shm::init_shm_global;
|
use smithay::wayland::shm::init_shm_global;
|
||||||
use smithay::wayland_server::Display;
|
|
||||||
use smithay::wayland_server::calloop::EventLoop;
|
use smithay::wayland_server::calloop::EventLoop;
|
||||||
use smithay::wayland_server::protocol::wl_output;
|
use smithay::wayland_server::protocol::wl_output;
|
||||||
use smithay::input::Libinput;
|
use smithay::wayland_server::Display;
|
||||||
|
|
||||||
use glium_drawer::GliumDrawer;
|
use glium_drawer::GliumDrawer;
|
||||||
use shell::{init_shell, MyWindowMap, Roles, SurfaceData};
|
|
||||||
use input_handler::AnvilInputHandler;
|
use input_handler::AnvilInputHandler;
|
||||||
|
use shell::{init_shell, MyWindowMap, Roles, SurfaceData};
|
||||||
|
|
||||||
pub fn run_udev(mut display: Display, mut event_loop: EventLoop<()>, log: Logger) -> Result<(), ()> {
|
pub fn run_udev(mut display: Display, mut event_loop: EventLoop<()>, log: Logger) -> Result<(), ()> {
|
||||||
let name = display.add_socket_auto().unwrap().into_string().unwrap();
|
let name = display.add_socket_auto().unwrap().into_string().unwrap();
|
||||||
|
@ -51,16 +51,9 @@ pub fn run_udev(mut display: Display, mut event_loop: EventLoop<()>, log: Logger
|
||||||
/*
|
/*
|
||||||
* Initialize the compositor
|
* Initialize the compositor
|
||||||
*/
|
*/
|
||||||
init_shm_global(
|
init_shm_global(&mut display.borrow_mut(), vec![], log.clone());
|
||||||
&mut display.borrow_mut(),
|
|
||||||
vec![],
|
|
||||||
log.clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let (compositor_token, _, _, window_map) = init_shell(
|
let (compositor_token, _, _, window_map) = init_shell(&mut display.borrow_mut(), log.clone());
|
||||||
&mut display.borrow_mut(),
|
|
||||||
log.clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize session
|
* Initialize session
|
||||||
|
@ -100,11 +93,7 @@ pub fn run_udev(mut display: Display, mut event_loop: EventLoop<()>, log: Logger
|
||||||
|
|
||||||
let udev_session_id = notifier.register(&mut udev_backend);
|
let udev_session_id = notifier.register(&mut udev_backend);
|
||||||
|
|
||||||
let (mut w_seat, _) = Seat::new(
|
let (mut w_seat, _) = Seat::new(&mut display.borrow_mut(), session.seat(), log.clone());
|
||||||
&mut display.borrow_mut(),
|
|
||||||
session.seat(),
|
|
||||||
log.clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let pointer = w_seat.add_pointer();
|
let pointer = w_seat.add_pointer();
|
||||||
let keyboard = w_seat
|
let keyboard = w_seat
|
||||||
|
@ -158,16 +147,16 @@ pub fn run_udev(mut display: Display, mut event_loop: EventLoop<()>, log: Logger
|
||||||
pointer_location,
|
pointer_location,
|
||||||
session,
|
session,
|
||||||
));
|
));
|
||||||
let libinput_event_source = libinput_bind(libinput_backend, event_loop.handle())
|
let libinput_event_source = libinput_bind(libinput_backend, event_loop.handle()).unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let session_event_source = auto_session_bind(notifier, &event_loop.handle())
|
let session_event_source = auto_session_bind(notifier, &event_loop.handle()).unwrap();
|
||||||
.unwrap();
|
let udev_event_source = udev_backend_bind(udev_backend).unwrap();
|
||||||
let udev_event_source = udev_backend_bind(udev_backend)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
while running.load(Ordering::SeqCst) {
|
while running.load(Ordering::SeqCst) {
|
||||||
if event_loop.dispatch(Some(::std::time::Duration::from_millis(16)), &mut ()).is_err() {
|
if event_loop
|
||||||
|
.dispatch(Some(::std::time::Duration::from_millis(16)), &mut ())
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
running.store(false, Ordering::SeqCst);
|
running.store(false, Ordering::SeqCst);
|
||||||
} else {
|
} else {
|
||||||
display.borrow_mut().flush_clients();
|
display.borrow_mut().flush_clients();
|
||||||
|
@ -268,10 +257,9 @@ impl UdevHandler<DrmHandlerImpl> for UdevHandlerImpl {
|
||||||
*self.active_egl_context.borrow_mut() = device.bind_wl_display(&*self.display.borrow()).ok();
|
*self.active_egl_context.borrow_mut() = device.bind_wl_display(&*self.display.borrow()).ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
let backends = Rc::new(RefCell::new(self.scan_connectors(
|
let backends = Rc::new(RefCell::new(
|
||||||
device,
|
self.scan_connectors(device, self.active_egl_context.clone()),
|
||||||
self.active_egl_context.clone(),
|
));
|
||||||
)));
|
|
||||||
self.backends.insert(device.device_id(), backends.clone());
|
self.backends.insert(device.device_id(), backends.clone());
|
||||||
|
|
||||||
Some(DrmHandlerImpl {
|
Some(DrmHandlerImpl {
|
||||||
|
@ -328,11 +316,7 @@ impl DrmHandler<SessionFdDrmDevice> for DrmHandlerImpl {
|
||||||
.set_cursor_position(x.trunc().abs() as u32, y.trunc().abs() as u32);
|
.set_cursor_position(x.trunc().abs() as u32, y.trunc().abs() as u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
drawer.draw_windows(
|
drawer.draw_windows(&*self.window_map.borrow(), self.compositor_token, &self.logger);
|
||||||
&*self.window_map.borrow(),
|
|
||||||
self.compositor_token,
|
|
||||||
&self.logger,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use smithay::utils::Rectangle;
|
use smithay::utils::Rectangle;
|
||||||
use smithay::wayland::compositor::{CompositorToken, SubsurfaceRole, SurfaceAttributes, TraversalAction};
|
|
||||||
use smithay::wayland::compositor::roles::Role;
|
use smithay::wayland::compositor::roles::Role;
|
||||||
use smithay::wayland::shell::xdg::{ToplevelSurface, XdgSurfaceRole};
|
use smithay::wayland::compositor::{CompositorToken, SubsurfaceRole, SurfaceAttributes, TraversalAction};
|
||||||
use smithay::wayland::shell::legacy::{ShellSurface, ShellSurfaceRole};
|
use smithay::wayland::shell::legacy::{ShellSurface, ShellSurfaceRole};
|
||||||
use smithay::wayland_server::Resource;
|
use smithay::wayland::shell::xdg::{ToplevelSurface, XdgSurfaceRole};
|
||||||
use smithay::wayland_server::protocol::wl_surface;
|
use smithay::wayland_server::protocol::wl_surface;
|
||||||
|
use smithay::wayland_server::Resource;
|
||||||
|
|
||||||
pub enum Kind<U, R, SD, D> {
|
pub enum Kind<U, R, SD, D> {
|
||||||
Xdg(ToplevelSurface<U, R, SD>),
|
Xdg(ToplevelSurface<U, R, SD>),
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use smithay::wayland::shm::init_shm_global;
|
use smithay::backend::graphics::egl::wayland::EGLWaylandExtensions;
|
||||||
use smithay::wayland::seat::Seat;
|
use smithay::backend::graphics::egl::EGLGraphicsBackend;
|
||||||
use smithay::wayland::output::{Mode, Output, PhysicalProperties};
|
|
||||||
use smithay::backend::input::InputBackend;
|
use smithay::backend::input::InputBackend;
|
||||||
use smithay::backend::winit;
|
use smithay::backend::winit;
|
||||||
use smithay::backend::graphics::egl::EGLGraphicsBackend;
|
use smithay::wayland::output::{Mode, Output, PhysicalProperties};
|
||||||
use smithay::backend::graphics::egl::wayland::EGLWaylandExtensions;
|
use smithay::wayland::seat::Seat;
|
||||||
use smithay::wayland_server::Display;
|
use smithay::wayland::shm::init_shm_global;
|
||||||
use smithay::wayland_server::calloop::EventLoop;
|
use smithay::wayland_server::calloop::EventLoop;
|
||||||
use smithay::wayland_server::protocol::wl_output;
|
use smithay::wayland_server::protocol::wl_output;
|
||||||
|
use smithay::wayland_server::Display;
|
||||||
|
|
||||||
use slog::Logger;
|
use slog::Logger;
|
||||||
|
|
||||||
use glium_drawer::GliumDrawer;
|
use glium_drawer::GliumDrawer;
|
||||||
use shell::init_shell;
|
|
||||||
use input_handler::AnvilInputHandler;
|
use input_handler::AnvilInputHandler;
|
||||||
|
use shell::init_shell;
|
||||||
|
|
||||||
pub fn run_winit(display: &mut Display, event_loop: &mut EventLoop<()>, log: Logger) -> Result<(), ()> {
|
pub fn run_winit(display: &mut Display, event_loop: &mut EventLoop<()>, log: Logger) -> Result<(), ()> {
|
||||||
let (renderer, mut input) = winit::init(log.clone()).map_err(|_| ())?;
|
let (renderer, mut input) = winit::init(log.clone()).map_err(|_| ())?;
|
||||||
|
@ -52,7 +52,8 @@ pub fn run_winit(display: &mut Display, event_loop: &mut EventLoop<()>, log: Log
|
||||||
let (mut seat, _) = Seat::new(display, "winit".into(), log.clone());
|
let (mut seat, _) = Seat::new(display, "winit".into(), log.clone());
|
||||||
|
|
||||||
let pointer = seat.add_pointer();
|
let pointer = seat.add_pointer();
|
||||||
let keyboard = seat.add_keyboard("", "fr", "oss", None, 1000, 500)
|
let keyboard = seat
|
||||||
|
.add_keyboard("", "fr", "oss", None, 1000, 500)
|
||||||
.expect("Failed to initialize the keyboard");
|
.expect("Failed to initialize the keyboard");
|
||||||
|
|
||||||
let (output, _) = Output::new(
|
let (output, _) = Output::new(
|
||||||
|
@ -100,10 +101,9 @@ pub fn run_winit(display: &mut Display, event_loop: &mut EventLoop<()>, log: Log
|
||||||
|
|
||||||
drawer.draw_windows(&*window_map.borrow(), compositor_token, &log);
|
drawer.draw_windows(&*window_map.borrow(), compositor_token, &log);
|
||||||
|
|
||||||
event_loop.dispatch(
|
event_loop
|
||||||
Some(::std::time::Duration::from_millis(16)),
|
.dispatch(Some(::std::time::Duration::from_millis(16)), &mut ())
|
||||||
&mut ()
|
.unwrap();
|
||||||
).unwrap();
|
|
||||||
display.flush_clients();
|
display.flush_clients();
|
||||||
|
|
||||||
window_map.borrow_mut().refresh();
|
window_map.borrow_mut().refresh();
|
||||||
|
|
4
build.rs
4
build.rs
|
@ -32,7 +32,7 @@ fn main() {
|
||||||
"EGL_KHR_image_base",
|
"EGL_KHR_image_base",
|
||||||
],
|
],
|
||||||
).write_bindings(gl_generator::GlobalGenerator, &mut file)
|
).write_bindings(gl_generator::GlobalGenerator, &mut file)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut file = File::create(&dest.join("gl_bindings.rs")).unwrap();
|
let mut file = File::create(&dest.join("gl_bindings.rs")).unwrap();
|
||||||
Registry::new(
|
Registry::new(
|
||||||
|
@ -42,5 +42,5 @@ fn main() {
|
||||||
Fallbacks::None,
|
Fallbacks::None,
|
||||||
["GL_OES_EGL_image"],
|
["GL_OES_EGL_image"],
|
||||||
).write_bindings(gl_generator::GlobalGenerator, &mut file)
|
).write_bindings(gl_generator::GlobalGenerator, &mut file)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
use super::DevPath;
|
|
||||||
use super::error::*;
|
use super::error::*;
|
||||||
use backend::graphics::GraphicsBackend;
|
use super::DevPath;
|
||||||
use backend::graphics::egl::{EGLContext, EGLGraphicsBackend, EGLSurface, PixelFormat, SwapBuffersError};
|
|
||||||
use backend::graphics::egl::error::Result as EGLResult;
|
use backend::graphics::egl::error::Result as EGLResult;
|
||||||
use backend::graphics::egl::native::{Gbm, GbmSurfaceArguments};
|
use backend::graphics::egl::native::{Gbm, GbmSurfaceArguments};
|
||||||
use backend::graphics::egl::wayland::{EGLDisplay, EGLWaylandExtensions};
|
use backend::graphics::egl::wayland::{EGLDisplay, EGLWaylandExtensions};
|
||||||
use drm::Device as BasicDevice;
|
use backend::graphics::egl::{EGLContext, EGLGraphicsBackend, EGLSurface, PixelFormat, SwapBuffersError};
|
||||||
use drm::control::{Device, ResourceInfo};
|
use backend::graphics::GraphicsBackend;
|
||||||
use drm::control::{connector, crtc, encoder, framebuffer, Mode};
|
use drm::control::{connector, crtc, encoder, framebuffer, Mode};
|
||||||
use gbm::{BufferObject, BufferObjectFlags, Device as GbmDevice, Format as GbmFormat, Surface as GbmSurface,
|
use drm::control::{Device, ResourceInfo};
|
||||||
SurfaceBufferHandle};
|
use drm::Device as BasicDevice;
|
||||||
|
use gbm::{
|
||||||
|
BufferObject, BufferObjectFlags, Device as GbmDevice, Format as GbmFormat, Surface as GbmSurface,
|
||||||
|
SurfaceBufferHandle,
|
||||||
|
};
|
||||||
use image::{ImageBuffer, Rgba};
|
use image::{ImageBuffer, Rgba};
|
||||||
use nix::libc::c_void;
|
use nix::libc::c_void;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
@ -54,19 +56,12 @@ impl<A: Device + 'static> DrmBackend<A> {
|
||||||
size: (w as u32, h as u32),
|
size: (w as u32, h as u32),
|
||||||
format: GbmFormat::XRGB8888,
|
format: GbmFormat::XRGB8888,
|
||||||
flags: BufferObjectFlags::SCANOUT | BufferObjectFlags::RENDERING,
|
flags: BufferObjectFlags::SCANOUT | BufferObjectFlags::RENDERING,
|
||||||
})
|
}).chain_err(|| ErrorKind::GbmInitFailed)?;
|
||||||
.chain_err(|| ErrorKind::GbmInitFailed)?;
|
|
||||||
|
|
||||||
// make it active for the first `crtc::set`
|
// make it active for the first `crtc::set`
|
||||||
// (which is needed before the first page_flip)
|
// (which is needed before the first page_flip)
|
||||||
unsafe {
|
unsafe { surface.make_current().chain_err(|| ErrorKind::FailedToSwap)? };
|
||||||
surface
|
surface.swap_buffers().chain_err(|| ErrorKind::FailedToSwap)?;
|
||||||
.make_current()
|
|
||||||
.chain_err(|| ErrorKind::FailedToSwap)?
|
|
||||||
};
|
|
||||||
surface
|
|
||||||
.swap_buffers()
|
|
||||||
.chain_err(|| ErrorKind::FailedToSwap)?;
|
|
||||||
|
|
||||||
// init the first screen
|
// init the first screen
|
||||||
// (must be done before calling page_flip for the first time)
|
// (must be done before calling page_flip for the first time)
|
||||||
|
@ -78,21 +73,11 @@ impl<A: Device + 'static> DrmBackend<A> {
|
||||||
|
|
||||||
// we need a framebuffer for the front buffer
|
// we need a framebuffer for the front buffer
|
||||||
let fb = framebuffer::create(&*context, &*front_bo).chain_err(|| {
|
let fb = framebuffer::create(&*context, &*front_bo).chain_err(|| {
|
||||||
ErrorKind::DrmDev(format!(
|
ErrorKind::DrmDev(format!("Error creating framebuffer on {:?}", context.dev_path()))
|
||||||
"Error creating framebuffer on {:?}",
|
|
||||||
context.dev_path()
|
|
||||||
))
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
debug!(log, "Initialize screen");
|
debug!(log, "Initialize screen");
|
||||||
crtc::set(
|
crtc::set(&*context, crtc, fb.handle(), &connectors, (0, 0), Some(mode)).chain_err(|| {
|
||||||
&*context,
|
|
||||||
crtc,
|
|
||||||
fb.handle(),
|
|
||||||
&connectors,
|
|
||||||
(0, 0),
|
|
||||||
Some(mode),
|
|
||||||
).chain_err(|| {
|
|
||||||
ErrorKind::DrmDev(format!(
|
ErrorKind::DrmDev(format!(
|
||||||
"Error setting crtc {:?} on {:?}",
|
"Error setting crtc {:?} on {:?}",
|
||||||
crtc,
|
crtc,
|
||||||
|
@ -108,8 +93,7 @@ impl<A: Device + 'static> DrmBackend<A> {
|
||||||
1,
|
1,
|
||||||
GbmFormat::ARGB8888,
|
GbmFormat::ARGB8888,
|
||||||
BufferObjectFlags::CURSOR | BufferObjectFlags::WRITE,
|
BufferObjectFlags::CURSOR | BufferObjectFlags::WRITE,
|
||||||
)
|
).chain_err(|| ErrorKind::GbmInitFailed)?,
|
||||||
.chain_err(|| ErrorKind::GbmInitFailed)?,
|
|
||||||
(0, 0),
|
(0, 0),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -149,7 +133,8 @@ impl<A: Device + 'static> DrmBackend<A> {
|
||||||
// check if the connector can handle the current mode
|
// check if the connector can handle the current mode
|
||||||
if info.modes().contains(&self.mode) {
|
if info.modes().contains(&self.mode) {
|
||||||
// check if there is a valid encoder
|
// check if there is a valid encoder
|
||||||
let encoders = info.encoders()
|
let encoders = info
|
||||||
|
.encoders()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|encoder| {
|
.map(|encoder| {
|
||||||
encoder::Info::load_from_device(&*self.backend.context, *encoder).chain_err(|| {
|
encoder::Info::load_from_device(&*self.backend.context, *encoder).chain_err(|| {
|
||||||
|
@ -158,8 +143,7 @@ impl<A: Device + 'static> DrmBackend<A> {
|
||||||
self.backend.context.dev_path()
|
self.backend.context.dev_path()
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
})
|
}).collect::<Result<Vec<encoder::Info>>>()?;
|
||||||
.collect::<Result<Vec<encoder::Info>>>()?;
|
|
||||||
|
|
||||||
// and if any encoder supports the selected crtc
|
// and if any encoder supports the selected crtc
|
||||||
let resource_handles = self.backend.context.resource_handles().chain_err(|| {
|
let resource_handles = self.backend.context.resource_handles().chain_err(|| {
|
||||||
|
@ -171,11 +155,11 @@ impl<A: Device + 'static> DrmBackend<A> {
|
||||||
if !encoders
|
if !encoders
|
||||||
.iter()
|
.iter()
|
||||||
.map(|encoder| encoder.possible_crtcs())
|
.map(|encoder| encoder.possible_crtcs())
|
||||||
.all(|crtc_list|
|
.all(|crtc_list| {
|
||||||
resource_handles
|
resource_handles
|
||||||
.filter_crtcs(crtc_list)
|
.filter_crtcs(crtc_list)
|
||||||
.contains(&self.backend.crtc)
|
.contains(&self.backend.crtc)
|
||||||
) {
|
}) {
|
||||||
bail!(ErrorKind::NoSuitableEncoder(info, self.backend.crtc));
|
bail!(ErrorKind::NoSuitableEncoder(info, self.backend.crtc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,8 +216,7 @@ impl<A: Device + 'static> DrmBackend<A> {
|
||||||
"Error loading connector info on {:?}",
|
"Error loading connector info on {:?}",
|
||||||
self.backend.context.dev_path()
|
self.backend.context.dev_path()
|
||||||
))
|
))
|
||||||
})?
|
})?.modes()
|
||||||
.modes()
|
|
||||||
.contains(&mode)
|
.contains(&mode)
|
||||||
{
|
{
|
||||||
bail!(ErrorKind::ModeNotSuitable(mode));
|
bail!(ErrorKind::ModeNotSuitable(mode));
|
||||||
|
@ -249,25 +232,19 @@ impl<A: Device + 'static> DrmBackend<A> {
|
||||||
self.backend.logger,
|
self.backend.logger,
|
||||||
"Reinitializing surface for new mode: {}:{}", w, h
|
"Reinitializing surface for new mode: {}:{}", w, h
|
||||||
);
|
);
|
||||||
let surface = self.backend
|
let surface = self
|
||||||
|
.backend
|
||||||
.context
|
.context
|
||||||
.create_surface(GbmSurfaceArguments {
|
.create_surface(GbmSurfaceArguments {
|
||||||
size: (w as u32, h as u32),
|
size: (w as u32, h as u32),
|
||||||
format: GbmFormat::XRGB8888,
|
format: GbmFormat::XRGB8888,
|
||||||
flags: BufferObjectFlags::SCANOUT | BufferObjectFlags::RENDERING,
|
flags: BufferObjectFlags::SCANOUT | BufferObjectFlags::RENDERING,
|
||||||
})
|
}).chain_err(|| ErrorKind::GbmInitFailed)?;
|
||||||
.chain_err(|| ErrorKind::GbmInitFailed)?;
|
|
||||||
|
|
||||||
// make it active for the first `crtc::set`
|
// make it active for the first `crtc::set`
|
||||||
// (which is needed before the first page_flip)
|
// (which is needed before the first page_flip)
|
||||||
unsafe {
|
unsafe { surface.make_current().chain_err(|| ErrorKind::FailedToSwap)? };
|
||||||
surface
|
surface.swap_buffers().chain_err(|| ErrorKind::FailedToSwap)?;
|
||||||
.make_current()
|
|
||||||
.chain_err(|| ErrorKind::FailedToSwap)?
|
|
||||||
};
|
|
||||||
surface
|
|
||||||
.swap_buffers()
|
|
||||||
.chain_err(|| ErrorKind::FailedToSwap)?;
|
|
||||||
|
|
||||||
// Clean up next_buffer
|
// Clean up next_buffer
|
||||||
{
|
{
|
||||||
|
@ -412,11 +389,7 @@ impl<A: Device + 'static> GraphicsBackend for DrmBackend<A> {
|
||||||
|
|
||||||
fn set_cursor_position(&self, x: u32, y: u32) -> Result<()> {
|
fn set_cursor_position(&self, x: u32, y: u32) -> Result<()> {
|
||||||
trace!(self.backend.logger, "Move the cursor to {},{}", x, y);
|
trace!(self.backend.logger, "Move the cursor to {},{}", x, y);
|
||||||
crtc::move_cursor(
|
crtc::move_cursor(&*self.backend.context, self.backend.crtc, (x as i32, y as i32)).chain_err(|| {
|
||||||
&*self.backend.context,
|
|
||||||
self.backend.crtc,
|
|
||||||
(x as i32, y as i32),
|
|
||||||
).chain_err(|| {
|
|
||||||
ErrorKind::DrmDev(format!(
|
ErrorKind::DrmDev(format!(
|
||||||
"Error moving cursor on {:?}",
|
"Error moving cursor on {:?}",
|
||||||
self.backend.context.dev_path()
|
self.backend.context.dev_path()
|
||||||
|
@ -433,15 +406,15 @@ impl<A: Device + 'static> GraphicsBackend for DrmBackend<A> {
|
||||||
debug!(self.backend.logger, "Importing cursor");
|
debug!(self.backend.logger, "Importing cursor");
|
||||||
|
|
||||||
// import the cursor into a buffer we can render
|
// import the cursor into a buffer we can render
|
||||||
let mut cursor = self.backend
|
let mut cursor = self
|
||||||
|
.backend
|
||||||
.context
|
.context
|
||||||
.create_buffer_object(
|
.create_buffer_object(
|
||||||
w,
|
w,
|
||||||
h,
|
h,
|
||||||
GbmFormat::ARGB8888,
|
GbmFormat::ARGB8888,
|
||||||
BufferObjectFlags::CURSOR | BufferObjectFlags::WRITE,
|
BufferObjectFlags::CURSOR | BufferObjectFlags::WRITE,
|
||||||
)
|
).chain_err(|| ErrorKind::GbmInitFailed)?;
|
||||||
.chain_err(|| ErrorKind::GbmInitFailed)?;
|
|
||||||
cursor
|
cursor
|
||||||
.write(&**buffer)
|
.write(&**buffer)
|
||||||
.chain_err(|| ErrorKind::GbmInitFailed)?
|
.chain_err(|| ErrorKind::GbmInitFailed)?
|
||||||
|
@ -495,7 +468,8 @@ impl<A: Device + 'static> EGLGraphicsBackend for DrmBackend<A> {
|
||||||
// would most likely result in a lot of flickering.
|
// would most likely result in a lot of flickering.
|
||||||
// neither weston, wlc or wlroots bother with that as well.
|
// neither weston, wlc or wlroots bother with that as well.
|
||||||
// so we just assume we got at least two buffers to do flipping.
|
// so we just assume we got at least two buffers to do flipping.
|
||||||
let mut next_bo = self.surface
|
let mut next_bo = self
|
||||||
|
.surface
|
||||||
.lock_front_buffer()
|
.lock_front_buffer()
|
||||||
.expect("Surface only has one front buffer. Not supported by smithay");
|
.expect("Surface only has one front buffer. Not supported by smithay");
|
||||||
|
|
||||||
|
|
|
@ -215,11 +215,11 @@ use backend::graphics::egl::native::Gbm;
|
||||||
use backend::graphics::egl::wayland::{EGLDisplay, EGLWaylandExtensions};
|
use backend::graphics::egl::wayland::{EGLDisplay, EGLWaylandExtensions};
|
||||||
#[cfg(feature = "backend_session")]
|
#[cfg(feature = "backend_session")]
|
||||||
use backend::session::{AsSessionObserver, SessionObserver};
|
use backend::session::{AsSessionObserver, SessionObserver};
|
||||||
use drm::Device as BasicDevice;
|
|
||||||
use drm::control::{connector, crtc, encoder, Mode, ResourceInfo};
|
|
||||||
use drm::control::Device as ControlDevice;
|
|
||||||
use drm::control::framebuffer;
|
use drm::control::framebuffer;
|
||||||
|
use drm::control::Device as ControlDevice;
|
||||||
|
use drm::control::{connector, crtc, encoder, Mode, ResourceInfo};
|
||||||
use drm::result::Error as DrmError;
|
use drm::result::Error as DrmError;
|
||||||
|
use drm::Device as BasicDevice;
|
||||||
use gbm::{BufferObject, Device as GbmDevice};
|
use gbm::{BufferObject, Device as GbmDevice};
|
||||||
use nix;
|
use nix;
|
||||||
use nix::sys::stat::{self, dev_t, fstat};
|
use nix::sys::stat::{self, dev_t, fstat};
|
||||||
|
@ -230,13 +230,13 @@ use std::io::Error as IoError;
|
||||||
use std::os::unix::io::{AsRawFd, RawFd};
|
use std::os::unix::io::{AsRawFd, RawFd};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::rc::{Rc, Weak};
|
use std::rc::{Rc, Weak};
|
||||||
use std::sync::{Arc, Once, ONCE_INIT};
|
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use std::sync::{Arc, Once, ONCE_INIT};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use wayland_server::calloop::generic::{EventedRawFd, Generic};
|
||||||
|
use wayland_server::calloop::{LoopHandle, Ready, Source};
|
||||||
use wayland_server::Display;
|
use wayland_server::Display;
|
||||||
use wayland_server::calloop::{LoopHandle, Source, Ready};
|
|
||||||
use wayland_server::calloop::generic::{Generic, EventedRawFd};
|
|
||||||
|
|
||||||
mod backend;
|
mod backend;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
@ -308,17 +308,19 @@ impl<A: ControlDevice + 'static> DrmDevice<A> {
|
||||||
|
|
||||||
let mut drm = DrmDevice {
|
let mut drm = DrmDevice {
|
||||||
// Open the gbm device from the drm device and create a context based on that
|
// Open the gbm device from the drm device and create a context based on that
|
||||||
context: Rc::new(EGLContext::new(
|
context: Rc::new(
|
||||||
{
|
EGLContext::new(
|
||||||
debug!(log, "Creating gbm device");
|
{
|
||||||
let gbm = GbmDevice::new(dev).chain_err(|| ErrorKind::GbmInitFailed)?;
|
debug!(log, "Creating gbm device");
|
||||||
debug!(log, "Creating egl context from gbm device");
|
let gbm = GbmDevice::new(dev).chain_err(|| ErrorKind::GbmInitFailed)?;
|
||||||
gbm
|
debug!(log, "Creating egl context from gbm device");
|
||||||
},
|
gbm
|
||||||
attributes,
|
},
|
||||||
Default::default(),
|
attributes,
|
||||||
log.clone(),
|
Default::default(),
|
||||||
).map_err(Error::from)?),
|
log.clone(),
|
||||||
|
).map_err(Error::from)?,
|
||||||
|
),
|
||||||
backends: Rc::new(RefCell::new(HashMap::new())),
|
backends: Rc::new(RefCell::new(HashMap::new())),
|
||||||
device_id,
|
device_id,
|
||||||
old_state: HashMap::new(),
|
old_state: HashMap::new(),
|
||||||
|
@ -331,32 +333,20 @@ impl<A: ControlDevice + 'static> DrmDevice<A> {
|
||||||
|
|
||||||
// we want to mode-set, so we better be the master, if we run via a tty session
|
// we want to mode-set, so we better be the master, if we run via a tty session
|
||||||
if drm.set_master().is_err() {
|
if drm.set_master().is_err() {
|
||||||
warn!(
|
warn!(log, "Unable to become drm master, assuming unpriviledged mode");
|
||||||
log,
|
|
||||||
"Unable to become drm master, assuming unpriviledged mode"
|
|
||||||
);
|
|
||||||
drm.priviledged = false;
|
drm.priviledged = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
let res_handles = drm.resource_handles().chain_err(|| {
|
let res_handles = drm.resource_handles().chain_err(|| {
|
||||||
ErrorKind::DrmDev(format!(
|
ErrorKind::DrmDev(format!("Error loading drm resources on {:?}", drm.dev_path()))
|
||||||
"Error loading drm resources on {:?}",
|
|
||||||
drm.dev_path()
|
|
||||||
))
|
|
||||||
})?;
|
})?;
|
||||||
for &con in res_handles.connectors() {
|
for &con in res_handles.connectors() {
|
||||||
let con_info = connector::Info::load_from_device(&drm, con).chain_err(|| {
|
let con_info = connector::Info::load_from_device(&drm, con).chain_err(|| {
|
||||||
ErrorKind::DrmDev(format!(
|
ErrorKind::DrmDev(format!("Error loading connector info on {:?}", drm.dev_path()))
|
||||||
"Error loading connector info on {:?}",
|
|
||||||
drm.dev_path()
|
|
||||||
))
|
|
||||||
})?;
|
})?;
|
||||||
if let Some(enc) = con_info.current_encoder() {
|
if let Some(enc) = con_info.current_encoder() {
|
||||||
let enc_info = encoder::Info::load_from_device(&drm, enc).chain_err(|| {
|
let enc_info = encoder::Info::load_from_device(&drm, enc).chain_err(|| {
|
||||||
ErrorKind::DrmDev(format!(
|
ErrorKind::DrmDev(format!("Error loading encoder info on {:?}", drm.dev_path()))
|
||||||
"Error loading encoder info on {:?}",
|
|
||||||
drm.dev_path()
|
|
||||||
))
|
|
||||||
})?;
|
})?;
|
||||||
if let Some(crtc) = enc_info.current_crtc() {
|
if let Some(crtc) = enc_info.current_crtc() {
|
||||||
let info = crtc::Info::load_from_device(&drm, crtc).chain_err(|| {
|
let info = crtc::Info::load_from_device(&drm, crtc).chain_err(|| {
|
||||||
|
@ -402,10 +392,7 @@ impl<A: ControlDevice + 'static> DrmDevice<A> {
|
||||||
// check if we have an encoder for every connector and the mode mode
|
// check if we have an encoder for every connector and the mode mode
|
||||||
for connector in &connectors {
|
for connector in &connectors {
|
||||||
let con_info = connector::Info::load_from_device(self, *connector).chain_err(|| {
|
let con_info = connector::Info::load_from_device(self, *connector).chain_err(|| {
|
||||||
ErrorKind::DrmDev(format!(
|
ErrorKind::DrmDev(format!("Error loading connector info on {:?}", self.dev_path()))
|
||||||
"Error loading connector info on {:?}",
|
|
||||||
self.dev_path()
|
|
||||||
))
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// check the mode
|
// check the mode
|
||||||
|
@ -419,20 +406,13 @@ impl<A: ControlDevice + 'static> DrmDevice<A> {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|encoder| {
|
.map(|encoder| {
|
||||||
encoder::Info::load_from_device(self, *encoder).chain_err(|| {
|
encoder::Info::load_from_device(self, *encoder).chain_err(|| {
|
||||||
ErrorKind::DrmDev(format!(
|
ErrorKind::DrmDev(format!("Error loading encoder info on {:?}", self.dev_path()))
|
||||||
"Error loading encoder info on {:?}",
|
|
||||||
self.dev_path()
|
|
||||||
))
|
|
||||||
})
|
})
|
||||||
})
|
}).collect::<Result<Vec<encoder::Info>>>()?;
|
||||||
.collect::<Result<Vec<encoder::Info>>>()?;
|
|
||||||
|
|
||||||
// and if any encoder supports the selected crtc
|
// and if any encoder supports the selected crtc
|
||||||
let resource_handles = self.resource_handles().chain_err(|| {
|
let resource_handles = self.resource_handles().chain_err(|| {
|
||||||
ErrorKind::DrmDev(format!(
|
ErrorKind::DrmDev(format!("Error loading drm resources on {:?}", self.dev_path()))
|
||||||
"Error loading drm resources on {:?}",
|
|
||||||
self.dev_path()
|
|
||||||
))
|
|
||||||
})?;
|
})?;
|
||||||
if !encoders
|
if !encoders
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -514,18 +494,12 @@ impl<A: ControlDevice + 'static> Drop for DrmDevice<A> {
|
||||||
info.position(),
|
info.position(),
|
||||||
info.mode(),
|
info.mode(),
|
||||||
) {
|
) {
|
||||||
error!(
|
error!(self.logger, "Failed to reset crtc ({:?}). Error: {}", handle, err);
|
||||||
self.logger,
|
|
||||||
"Failed to reset crtc ({:?}). Error: {}", handle, err
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.priviledged {
|
if self.priviledged {
|
||||||
if let Err(err) = self.drop_master() {
|
if let Err(err) = self.drop_master() {
|
||||||
error!(
|
error!(self.logger, "Failed to drop drm master state. Error: {}", err);
|
||||||
self.logger,
|
|
||||||
"Failed to drop drm master state. Error: {}", err
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -563,17 +537,13 @@ where
|
||||||
let mut source = Generic::from_raw_fd(fd);
|
let mut source = Generic::from_raw_fd(fd);
|
||||||
source.set_interest(Ready::readable());
|
source.set_interest(Ready::readable());
|
||||||
|
|
||||||
match handle.insert_source(
|
match handle.insert_source(source, {
|
||||||
source,
|
let device = device.clone();
|
||||||
{
|
move |_evt, _| {
|
||||||
let device = device.clone();
|
let mut device = device.borrow_mut();
|
||||||
move |_evt, _| {
|
process_events(&mut *device, &mut handler);
|
||||||
let mut device = device.borrow_mut();
|
|
||||||
process_events(&mut *device, &mut handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
) {
|
}) {
|
||||||
Ok(source) => Ok((source, device)),
|
Ok(source) => Ok((source, device)),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let device = Rc::try_unwrap(device).unwrap_or_else(|_| unreachable!());
|
let device = Rc::try_unwrap(device).unwrap_or_else(|_| unreachable!());
|
||||||
|
@ -583,7 +553,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_events<A, H>(device: &mut DrmDevice<A>, handler: &mut H)
|
fn process_events<A, H>(device: &mut DrmDevice<A>, handler: &mut H)
|
||||||
where
|
where
|
||||||
A: ControlDevice + 'static,
|
A: ControlDevice + 'static,
|
||||||
H: DrmHandler<A> + 'static,
|
H: DrmHandler<A> + 'static,
|
||||||
{
|
{
|
||||||
|
@ -592,18 +562,12 @@ where
|
||||||
if let crtc::Event::PageFlip(event) = event {
|
if let crtc::Event::PageFlip(event) = event {
|
||||||
if device.active.load(Ordering::SeqCst) {
|
if device.active.load(Ordering::SeqCst) {
|
||||||
let backends = device.backends.borrow().clone();
|
let backends = device.backends.borrow().clone();
|
||||||
if let Some(backend) = backends
|
if let Some(backend) = backends.get(&event.crtc).iter().flat_map(|x| x.upgrade()).next() {
|
||||||
.get(&event.crtc)
|
|
||||||
.iter()
|
|
||||||
.flat_map(|x| x.upgrade())
|
|
||||||
.next()
|
|
||||||
{
|
|
||||||
// we can now unlock the buffer
|
// we can now unlock the buffer
|
||||||
backend.unlock_buffer();
|
backend.unlock_buffer();
|
||||||
trace!(device.logger, "Handling event for backend {:?}", event.crtc);
|
trace!(device.logger, "Handling event for backend {:?}", event.crtc);
|
||||||
// and then call the user to render the next frame
|
// and then call the user to render the next frame
|
||||||
handler
|
handler.ready(device, event.crtc, event.frame, event.duration);
|
||||||
.ready(device, event.crtc, event.frame, event.duration);
|
|
||||||
} else {
|
} else {
|
||||||
device.backends.borrow_mut().remove(&event.crtc);
|
device.backends.borrow_mut().remove(&event.crtc);
|
||||||
}
|
}
|
||||||
|
@ -658,10 +622,7 @@ impl<A: ControlDevice + 'static> SessionObserver for DrmDeviceObserver<A> {
|
||||||
info.position(),
|
info.position(),
|
||||||
info.mode(),
|
info.mode(),
|
||||||
) {
|
) {
|
||||||
error!(
|
error!(self.logger, "Failed to reset crtc ({:?}). Error: {}", handle, err);
|
||||||
self.logger,
|
|
||||||
"Failed to reset crtc ({:?}). Error: {}", handle, err
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -669,10 +630,7 @@ impl<A: ControlDevice + 'static> SessionObserver for DrmDeviceObserver<A> {
|
||||||
if self.priviledged {
|
if self.priviledged {
|
||||||
if let Some(device) = self.context.upgrade() {
|
if let Some(device) = self.context.upgrade() {
|
||||||
if let Err(err) = device.drop_master() {
|
if let Err(err) = device.drop_master() {
|
||||||
error!(
|
error!(self.logger, "Failed to drop drm master state. Error: {}", err);
|
||||||
self.logger,
|
|
||||||
"Failed to drop drm master state. Error: {}", err
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -694,11 +652,7 @@ impl<A: ControlDevice + 'static> SessionObserver for DrmDeviceObserver<A> {
|
||||||
if self.priviledged {
|
if self.priviledged {
|
||||||
if let Some(device) = self.context.upgrade() {
|
if let Some(device) = self.context.upgrade() {
|
||||||
if let Err(err) = device.set_master() {
|
if let Err(err) = device.set_master() {
|
||||||
crit!(
|
crit!(self.logger, "Failed to acquire drm master again. Error: {}", err);
|
||||||
self.logger,
|
|
||||||
"Failed to acquire drm master again. Error: {}",
|
|
||||||
err
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
//! EGL context related structs
|
//! EGL context related structs
|
||||||
|
|
||||||
use super::{ffi, EGLSurface, PixelFormat};
|
|
||||||
use super::error::*;
|
use super::error::*;
|
||||||
use super::native;
|
use super::native;
|
||||||
#[cfg(feature = "backend_drm")]
|
use super::{ffi, EGLSurface, PixelFormat};
|
||||||
use drm::Device as BasicDevice;
|
|
||||||
#[cfg(feature = "backend_drm")]
|
#[cfg(feature = "backend_drm")]
|
||||||
use drm::control::Device as ControlDevice;
|
use drm::control::Device as ControlDevice;
|
||||||
#[cfg(feature = "backend_drm")]
|
#[cfg(feature = "backend_drm")]
|
||||||
|
use drm::Device as BasicDevice;
|
||||||
|
#[cfg(feature = "backend_drm")]
|
||||||
use gbm::Device as GbmDevice;
|
use gbm::Device as GbmDevice;
|
||||||
use nix::libc::{c_int, c_void};
|
use nix::libc::{c_int, c_void};
|
||||||
use slog;
|
use slog;
|
||||||
|
@ -89,17 +89,15 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLContext<B, N> {
|
||||||
mut attributes: GlAttributes,
|
mut attributes: GlAttributes,
|
||||||
reqs: PixelFormatRequirements,
|
reqs: PixelFormatRequirements,
|
||||||
log: ::slog::Logger,
|
log: ::slog::Logger,
|
||||||
) -> Result<
|
) -> Result<(
|
||||||
(
|
Rc<ffi::egl::types::EGLContext>,
|
||||||
Rc<ffi::egl::types::EGLContext>,
|
Rc<ffi::egl::types::EGLDisplay>,
|
||||||
Rc<ffi::egl::types::EGLDisplay>,
|
ffi::egl::types::EGLConfig,
|
||||||
ffi::egl::types::EGLConfig,
|
Vec<c_int>,
|
||||||
Vec<c_int>,
|
PixelFormat,
|
||||||
PixelFormat,
|
bool,
|
||||||
bool,
|
bool,
|
||||||
bool,
|
)> {
|
||||||
),
|
|
||||||
> {
|
|
||||||
// If no version is given, try OpenGLES 3.0, if available,
|
// If no version is given, try OpenGLES 3.0, if available,
|
||||||
// fallback to 2.0 otherwise
|
// fallback to 2.0 otherwise
|
||||||
let version = match attributes.version {
|
let version = match attributes.version {
|
||||||
|
@ -119,10 +117,7 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLContext<B, N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some((1, x)) => {
|
Some((1, x)) => {
|
||||||
error!(
|
error!(log, "OpenGLES 1.* is not supported by the EGL renderer backend");
|
||||||
log,
|
|
||||||
"OpenGLES 1.* is not supported by the EGL renderer backend"
|
|
||||||
);
|
|
||||||
bail!(ErrorKind::OpenGlVersionNotSupported((1, x)));
|
bail!(ErrorKind::OpenGlVersionNotSupported((1, x)));
|
||||||
}
|
}
|
||||||
Some(version) => {
|
Some(version) => {
|
||||||
|
@ -178,11 +173,7 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLContext<B, N> {
|
||||||
|
|
||||||
debug!(log, "EGL No-Display Extensions: {:?}", dp_extensions);
|
debug!(log, "EGL No-Display Extensions: {:?}", dp_extensions);
|
||||||
|
|
||||||
let display = B::get_display(
|
let display = B::get_display(ptr, |e: &str| dp_extensions.iter().any(|s| s == e), log.clone());
|
||||||
ptr,
|
|
||||||
|e: &str| dp_extensions.iter().any(|s| s == e),
|
|
||||||
log.clone(),
|
|
||||||
);
|
|
||||||
if display == ffi::egl::NO_DISPLAY {
|
if display == ffi::egl::NO_DISPLAY {
|
||||||
error!(log, "EGL Display is not valid");
|
error!(log, "EGL Display is not valid");
|
||||||
bail!(ErrorKind::DisplayNotSupported);
|
bail!(ErrorKind::DisplayNotSupported);
|
||||||
|
@ -215,10 +206,7 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLContext<B, N> {
|
||||||
info!(log, "EGL Extensions: {:?}", extensions);
|
info!(log, "EGL Extensions: {:?}", extensions);
|
||||||
|
|
||||||
if egl_version >= (1, 2) && ffi::egl::BindAPI(ffi::egl::OPENGL_ES_API) == 0 {
|
if egl_version >= (1, 2) && ffi::egl::BindAPI(ffi::egl::OPENGL_ES_API) == 0 {
|
||||||
error!(
|
error!(log, "OpenGLES not supported by the underlying EGL implementation");
|
||||||
log,
|
|
||||||
"OpenGLES not supported by the underlying EGL implementation"
|
|
||||||
);
|
|
||||||
bail!(ErrorKind::OpenGlesNotSupported);
|
bail!(ErrorKind::OpenGlesNotSupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,14 +327,7 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLContext<B, N> {
|
||||||
// calling `eglChooseConfig`
|
// calling `eglChooseConfig`
|
||||||
let mut config_id = mem::uninitialized();
|
let mut config_id = mem::uninitialized();
|
||||||
let mut num_configs = mem::uninitialized();
|
let mut num_configs = mem::uninitialized();
|
||||||
if ffi::egl::ChooseConfig(
|
if ffi::egl::ChooseConfig(display, descriptor.as_ptr(), &mut config_id, 1, &mut num_configs) == 0 {
|
||||||
display,
|
|
||||||
descriptor.as_ptr(),
|
|
||||||
&mut config_id,
|
|
||||||
1,
|
|
||||||
&mut num_configs,
|
|
||||||
) == 0
|
|
||||||
{
|
|
||||||
bail!(ErrorKind::ConfigFailed);
|
bail!(ErrorKind::ConfigFailed);
|
||||||
}
|
}
|
||||||
if num_configs == 0 {
|
if num_configs == 0 {
|
||||||
|
@ -356,17 +337,14 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLContext<B, N> {
|
||||||
|
|
||||||
// analyzing each config
|
// analyzing each config
|
||||||
macro_rules! attrib {
|
macro_rules! attrib {
|
||||||
($display:expr, $config:expr, $attr:expr) => (
|
($display:expr, $config:expr, $attr:expr) => {{
|
||||||
{
|
let mut value = mem::uninitialized();
|
||||||
let mut value = mem::uninitialized();
|
let res = ffi::egl::GetConfigAttrib($display, $config, $attr as ffi::egl::types::EGLint, &mut value);
|
||||||
let res = ffi::egl::GetConfigAttrib($display, $config,
|
if res == 0 {
|
||||||
$attr as ffi::egl::types::EGLint, &mut value);
|
bail!(ErrorKind::ConfigFailed);
|
||||||
if res == 0 {
|
|
||||||
bail!(ErrorKind::ConfigFailed);
|
|
||||||
}
|
|
||||||
value
|
|
||||||
}
|
}
|
||||||
)
|
value
|
||||||
|
}};
|
||||||
};
|
};
|
||||||
|
|
||||||
let desc = PixelFormat {
|
let desc = PixelFormat {
|
||||||
|
@ -450,12 +428,7 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLContext<B, N> {
|
||||||
info!(log, "EGL context created");
|
info!(log, "EGL context created");
|
||||||
|
|
||||||
// make current and get list of gl extensions
|
// make current and get list of gl extensions
|
||||||
ffi::egl::MakeCurrent(
|
ffi::egl::MakeCurrent(display as *const _, ptr::null(), ptr::null(), context as *const _);
|
||||||
display as *const _,
|
|
||||||
ptr::null(),
|
|
||||||
ptr::null(),
|
|
||||||
context as *const _,
|
|
||||||
);
|
|
||||||
|
|
||||||
// the list of gl extensions supported by the context
|
// the list of gl extensions supported by the context
|
||||||
let gl_extensions = {
|
let gl_extensions = {
|
||||||
|
@ -474,9 +447,7 @@ impl<B: native::Backend, N: native::NativeDisplay<B>> EGLContext<B, N> {
|
||||||
config_id,
|
config_id,
|
||||||
surface_attributes,
|
surface_attributes,
|
||||||
desc,
|
desc,
|
||||||
extensions
|
extensions.iter().any(|s| *s == "EGL_WL_bind_wayland_display"),
|
||||||
.iter()
|
|
||||||
.any(|s| *s == "EGL_WL_bind_wayland_display"),
|
|
||||||
gl_extensions
|
gl_extensions
|
||||||
.iter()
|
.iter()
|
||||||
.any(|s| *s == "GL_OES_EGL_image" || *s == "GL_OES_EGL_image_base"),
|
.any(|s| *s == "GL_OES_EGL_image" || *s == "GL_OES_EGL_image_base"),
|
||||||
|
|
|
@ -25,9 +25,7 @@ pub mod egl {
|
||||||
use std::sync::{Once, ONCE_INIT};
|
use std::sync::{Once, ONCE_INIT};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref LIB: Library = {
|
pub static ref LIB: Library = { Library::new("libEGL.so.1").expect("Failed to load LibEGL") };
|
||||||
Library::new("libEGL.so.1").expect("Failed to load LibEGL")
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static LOAD: Once = ONCE_INIT;
|
pub static LOAD: Once = ONCE_INIT;
|
||||||
|
@ -101,9 +99,9 @@ pub mod egl {
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub mod BindWaylandDisplayWL {
|
pub mod BindWaylandDisplayWL {
|
||||||
use super::{metaloadfn, wayland_storage};
|
|
||||||
use super::FnPtr;
|
use super::FnPtr;
|
||||||
use super::__gl_imports::raw;
|
use super::__gl_imports::raw;
|
||||||
|
use super::{metaloadfn, wayland_storage};
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
@ -125,9 +123,9 @@ pub mod egl {
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub mod UnbindWaylandDisplayWL {
|
pub mod UnbindWaylandDisplayWL {
|
||||||
use super::{metaloadfn, wayland_storage};
|
|
||||||
use super::FnPtr;
|
use super::FnPtr;
|
||||||
use super::__gl_imports::raw;
|
use super::__gl_imports::raw;
|
||||||
|
use super::{metaloadfn, wayland_storage};
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
@ -149,9 +147,9 @@ pub mod egl {
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub mod QueryWaylandBufferWL {
|
pub mod QueryWaylandBufferWL {
|
||||||
use super::{metaloadfn, wayland_storage};
|
|
||||||
use super::FnPtr;
|
use super::FnPtr;
|
||||||
use super::__gl_imports::raw;
|
use super::__gl_imports::raw;
|
||||||
|
use super::{metaloadfn, wayland_storage};
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
|
|
@ -13,7 +13,12 @@ use std::fmt;
|
||||||
pub mod context;
|
pub mod context;
|
||||||
pub use self::context::EGLContext;
|
pub use self::context::EGLContext;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
#[allow(non_camel_case_types, dead_code, unused_mut, non_upper_case_globals)]
|
#[allow(
|
||||||
|
non_camel_case_types,
|
||||||
|
dead_code,
|
||||||
|
unused_mut,
|
||||||
|
non_upper_case_globals
|
||||||
|
)]
|
||||||
pub mod ffi;
|
pub mod ffi;
|
||||||
pub mod native;
|
pub mod native;
|
||||||
pub mod surface;
|
pub mod surface;
|
||||||
|
|
|
@ -15,9 +15,9 @@ use std::ptr;
|
||||||
#[cfg(feature = "backend_winit")]
|
#[cfg(feature = "backend_winit")]
|
||||||
use wayland_client::egl as wegl;
|
use wayland_client::egl as wegl;
|
||||||
#[cfg(feature = "backend_winit")]
|
#[cfg(feature = "backend_winit")]
|
||||||
use winit::Window as WinitWindow;
|
|
||||||
#[cfg(feature = "backend_winit")]
|
|
||||||
use winit::os::unix::WindowExt;
|
use winit::os::unix::WindowExt;
|
||||||
|
#[cfg(feature = "backend_winit")]
|
||||||
|
use winit::Window as WinitWindow;
|
||||||
|
|
||||||
/// Trait for typed backend variants (X11/Wayland/GBM)
|
/// Trait for typed backend variants (X11/Wayland/GBM)
|
||||||
pub trait Backend {
|
pub trait Backend {
|
||||||
|
@ -53,26 +53,12 @@ impl Backend for Wayland {
|
||||||
F: Fn(&str) -> bool,
|
F: Fn(&str) -> bool,
|
||||||
{
|
{
|
||||||
if has_dp_extension("EGL_KHR_platform_wayland") && ffi::egl::GetPlatformDisplay::is_loaded() {
|
if has_dp_extension("EGL_KHR_platform_wayland") && ffi::egl::GetPlatformDisplay::is_loaded() {
|
||||||
trace!(
|
trace!(log, "EGL Display Initialization via EGL_KHR_platform_wayland");
|
||||||
log,
|
ffi::egl::GetPlatformDisplay(ffi::egl::PLATFORM_WAYLAND_KHR, display as *mut _, ptr::null())
|
||||||
"EGL Display Initialization via EGL_KHR_platform_wayland"
|
|
||||||
);
|
|
||||||
ffi::egl::GetPlatformDisplay(
|
|
||||||
ffi::egl::PLATFORM_WAYLAND_KHR,
|
|
||||||
display as *mut _,
|
|
||||||
ptr::null(),
|
|
||||||
)
|
|
||||||
} else if has_dp_extension("EGL_EXT_platform_wayland") && ffi::egl::GetPlatformDisplayEXT::is_loaded()
|
} else if has_dp_extension("EGL_EXT_platform_wayland") && ffi::egl::GetPlatformDisplayEXT::is_loaded()
|
||||||
{
|
{
|
||||||
trace!(
|
trace!(log, "EGL Display Initialization via EGL_EXT_platform_wayland");
|
||||||
log,
|
ffi::egl::GetPlatformDisplayEXT(ffi::egl::PLATFORM_WAYLAND_EXT, display as *mut _, ptr::null())
|
||||||
"EGL Display Initialization via EGL_EXT_platform_wayland"
|
|
||||||
);
|
|
||||||
ffi::egl::GetPlatformDisplayEXT(
|
|
||||||
ffi::egl::PLATFORM_WAYLAND_EXT,
|
|
||||||
display as *mut _,
|
|
||||||
ptr::null(),
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
trace!(log, "Default EGL Display Initialization via GetDisplay");
|
trace!(log, "Default EGL Display Initialization via GetDisplay");
|
||||||
ffi::egl::GetDisplay(display as *mut _)
|
ffi::egl::GetDisplay(display as *mut _)
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
//! EGL surface related structs
|
//! EGL surface related structs
|
||||||
|
|
||||||
use super::{EGLContext, SwapBuffersError};
|
|
||||||
use super::error::*;
|
use super::error::*;
|
||||||
use super::ffi;
|
use super::ffi;
|
||||||
use super::native;
|
use super::native;
|
||||||
|
use super::{EGLContext, SwapBuffersError};
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::rc::{Rc, Weak};
|
use std::rc::{Rc, Weak};
|
||||||
|
|
||||||
|
|
|
@ -10,14 +10,14 @@
|
||||||
//! You may then use the resulting `EGLDisplay` to recieve `EGLImages` of an egl-based `WlBuffer`
|
//! You may then use the resulting `EGLDisplay` to recieve `EGLImages` of an egl-based `WlBuffer`
|
||||||
//! for rendering.
|
//! for rendering.
|
||||||
|
|
||||||
use backend::graphics::egl::{ffi, native, EGLContext, EglExtensionNotSupportedError};
|
|
||||||
use backend::graphics::egl::error::*;
|
use backend::graphics::egl::error::*;
|
||||||
use backend::graphics::egl::ffi::egl::types::EGLImage;
|
use backend::graphics::egl::ffi::egl::types::EGLImage;
|
||||||
|
use backend::graphics::egl::{ffi, native, EGLContext, EglExtensionNotSupportedError};
|
||||||
use nix::libc::c_uint;
|
use nix::libc::c_uint;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::rc::{Rc, Weak};
|
use std::rc::{Rc, Weak};
|
||||||
use wayland_server::{Display, Resource};
|
|
||||||
use wayland_server::protocol::wl_buffer::{self, WlBuffer};
|
use wayland_server::protocol::wl_buffer::{self, WlBuffer};
|
||||||
|
use wayland_server::{Display, Resource};
|
||||||
use wayland_sys::server::wl_display;
|
use wayland_sys::server::wl_display;
|
||||||
|
|
||||||
/// Error that can occur when accessing an EGL buffer
|
/// Error that can occur when accessing an EGL buffer
|
||||||
|
@ -110,12 +110,9 @@ impl fmt::Display for TextureCreationError {
|
||||||
match *self {
|
match *self {
|
||||||
TextureCreationError::ContextLost => write!(formatter, "{}", self.description()),
|
TextureCreationError::ContextLost => write!(formatter, "{}", self.description()),
|
||||||
TextureCreationError::PlaneIndexOutOfBounds => write!(formatter, "{}", self.description()),
|
TextureCreationError::PlaneIndexOutOfBounds => write!(formatter, "{}", self.description()),
|
||||||
TextureCreationError::TextureBindingFailed(code) => write!(
|
TextureCreationError::TextureBindingFailed(code) => {
|
||||||
formatter,
|
write!(formatter, "{}. Gl error code: {:?}", self.description(), code)
|
||||||
"{}. Gl error code: {:?}",
|
}
|
||||||
self.description(),
|
|
||||||
code
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,7 +200,8 @@ impl EGLImages {
|
||||||
ffi::gl::BindTexture(ffi::gl::TEXTURE_2D, tex_id);
|
ffi::gl::BindTexture(ffi::gl::TEXTURE_2D, tex_id);
|
||||||
ffi::gl::EGLImageTargetTexture2DOES(
|
ffi::gl::EGLImageTargetTexture2DOES(
|
||||||
ffi::gl::TEXTURE_2D,
|
ffi::gl::TEXTURE_2D,
|
||||||
*self.images
|
*self
|
||||||
|
.images
|
||||||
.get(plane)
|
.get(plane)
|
||||||
.ok_or(TextureCreationError::PlaneIndexOutOfBounds)?,
|
.ok_or(TextureCreationError::PlaneIndexOutOfBounds)?,
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
//! Glium compatibility module
|
//! Glium compatibility module
|
||||||
|
|
||||||
use backend::graphics::egl::{EGLGraphicsBackend, SwapBuffersError};
|
|
||||||
use backend::graphics::egl::error::Result as EGLResult;
|
use backend::graphics::egl::error::Result as EGLResult;
|
||||||
use backend::graphics::egl::wayland::{EGLDisplay, EGLWaylandExtensions};
|
use backend::graphics::egl::wayland::{EGLDisplay, EGLWaylandExtensions};
|
||||||
use glium::Frame;
|
use backend::graphics::egl::{EGLGraphicsBackend, SwapBuffersError};
|
||||||
use glium::SwapBuffersError as GliumSwapBuffersError;
|
|
||||||
use glium::backend::{Backend, Context, Facade};
|
use glium::backend::{Backend, Context, Facade};
|
||||||
use glium::debug::DebugCallbackBehavior;
|
use glium::debug::DebugCallbackBehavior;
|
||||||
|
use glium::Frame;
|
||||||
|
use glium::SwapBuffersError as GliumSwapBuffersError;
|
||||||
use std::cell::{Ref, RefCell, RefMut};
|
use std::cell::{Ref, RefCell, RefMut};
|
||||||
use std::os::raw::c_void;
|
use std::os::raw::c_void;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
@ -51,10 +51,7 @@ impl<T: EGLGraphicsBackend + 'static> GliumGraphicsBackend<T> {
|
||||||
/// Note that destroying a `Frame` is immediate, even if vsync is enabled.
|
/// Note that destroying a `Frame` is immediate, even if vsync is enabled.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn draw(&self) -> Frame {
|
pub fn draw(&self) -> Frame {
|
||||||
Frame::new(
|
Frame::new(self.context.clone(), self.backend.get_framebuffer_dimensions())
|
||||||
self.context.clone(),
|
|
||||||
self.backend.get_framebuffer_dimensions(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Borrow the underlying backend.
|
/// Borrow the underlying backend.
|
||||||
|
|
|
@ -36,7 +36,7 @@ pub trait GraphicsBackend {
|
||||||
) -> Result<(), Self::Error>;
|
) -> Result<(), Self::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod software;
|
|
||||||
pub mod egl;
|
pub mod egl;
|
||||||
#[cfg(feature = "renderer_glium")]
|
#[cfg(feature = "renderer_glium")]
|
||||||
pub mod glium;
|
pub mod glium;
|
||||||
|
pub mod software;
|
||||||
|
|
|
@ -12,8 +12,8 @@ use std::io::Error as IoError;
|
||||||
use std::os::unix::io::RawFd;
|
use std::os::unix::io::RawFd;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use wayland_server::calloop::{LoopHandle, Source, Ready};
|
use wayland_server::calloop::generic::{EventedRawFd, Generic};
|
||||||
use wayland_server::calloop::generic::{Generic, EventedRawFd};
|
use wayland_server::calloop::{LoopHandle, Ready, Source};
|
||||||
|
|
||||||
// No idea if this is the same across unix platforms
|
// No idea if this is the same across unix platforms
|
||||||
// Lets make this linux exclusive for now, once someone tries to build it for
|
// Lets make this linux exclusive for now, once someone tries to build it for
|
||||||
|
@ -355,15 +355,18 @@ impl backend::InputBackend for LibinputInputBackend {
|
||||||
// update capabilities, so they appear correctly on `on_seat_changed` and `on_seat_destroyed`.
|
// update capabilities, so they appear correctly on `on_seat_changed` and `on_seat_destroyed`.
|
||||||
if let Some(seat) = self.seats.get_mut(&device_seat) {
|
if let Some(seat) = self.seats.get_mut(&device_seat) {
|
||||||
let caps = seat.capabilities_mut();
|
let caps = seat.capabilities_mut();
|
||||||
caps.pointer = self.devices
|
caps.pointer = self
|
||||||
|
.devices
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|x| x.seat() == device_seat)
|
.filter(|x| x.seat() == device_seat)
|
||||||
.any(|x| x.has_capability(libinput::DeviceCapability::Pointer));
|
.any(|x| x.has_capability(libinput::DeviceCapability::Pointer));
|
||||||
caps.keyboard = self.devices
|
caps.keyboard = self
|
||||||
|
.devices
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|x| x.seat() == device_seat)
|
.filter(|x| x.seat() == device_seat)
|
||||||
.any(|x| x.has_capability(libinput::DeviceCapability::Keyboard));
|
.any(|x| x.has_capability(libinput::DeviceCapability::Keyboard));
|
||||||
caps.touch = self.devices
|
caps.touch = self
|
||||||
|
.devices
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|x| x.seat() == device_seat)
|
.filter(|x| x.seat() == device_seat)
|
||||||
.any(|x| x.has_capability(libinput::DeviceCapability::Touch));
|
.any(|x| x.has_capability(libinput::DeviceCapability::Touch));
|
||||||
|
@ -411,11 +414,7 @@ impl backend::InputBackend for LibinputInputBackend {
|
||||||
handler.on_touch_down(seat, down_event)
|
handler.on_touch_down(seat, down_event)
|
||||||
}
|
}
|
||||||
TouchEvent::Motion(motion_event) => {
|
TouchEvent::Motion(motion_event) => {
|
||||||
trace!(
|
trace!(self.logger, "Calling on_touch_motion with {:?}", motion_event);
|
||||||
self.logger,
|
|
||||||
"Calling on_touch_motion with {:?}",
|
|
||||||
motion_event
|
|
||||||
);
|
|
||||||
handler.on_touch_motion(seat, motion_event)
|
handler.on_touch_motion(seat, motion_event)
|
||||||
}
|
}
|
||||||
TouchEvent::Up(up_event) => {
|
TouchEvent::Up(up_event) => {
|
||||||
|
@ -423,11 +422,7 @@ impl backend::InputBackend for LibinputInputBackend {
|
||||||
handler.on_touch_up(seat, up_event)
|
handler.on_touch_up(seat, up_event)
|
||||||
}
|
}
|
||||||
TouchEvent::Cancel(cancel_event) => {
|
TouchEvent::Cancel(cancel_event) => {
|
||||||
trace!(
|
trace!(self.logger, "Calling on_touch_cancel with {:?}", cancel_event);
|
||||||
self.logger,
|
|
||||||
"Calling on_touch_cancel with {:?}",
|
|
||||||
cancel_event
|
|
||||||
);
|
|
||||||
handler.on_touch_cancel(seat, cancel_event)
|
handler.on_touch_cancel(seat, cancel_event)
|
||||||
}
|
}
|
||||||
TouchEvent::Frame(frame_event) => {
|
TouchEvent::Frame(frame_event) => {
|
||||||
|
@ -463,11 +458,7 @@ impl backend::InputBackend for LibinputInputBackend {
|
||||||
if let Some(ref seat) = self.seats.get(&device_seat) {
|
if let Some(ref seat) = self.seats.get(&device_seat) {
|
||||||
match pointer_event {
|
match pointer_event {
|
||||||
PointerEvent::Motion(motion_event) => {
|
PointerEvent::Motion(motion_event) => {
|
||||||
trace!(
|
trace!(self.logger, "Calling on_pointer_move with {:?}", motion_event);
|
||||||
self.logger,
|
|
||||||
"Calling on_pointer_move with {:?}",
|
|
||||||
motion_event
|
|
||||||
);
|
|
||||||
handler.on_pointer_move(seat, motion_event);
|
handler.on_pointer_move(seat, motion_event);
|
||||||
}
|
}
|
||||||
PointerEvent::MotionAbsolute(motion_abs_event) => {
|
PointerEvent::MotionAbsolute(motion_abs_event) => {
|
||||||
|
@ -483,11 +474,7 @@ impl backend::InputBackend for LibinputInputBackend {
|
||||||
handler.on_pointer_axis(seat, axis_event);
|
handler.on_pointer_axis(seat, axis_event);
|
||||||
}
|
}
|
||||||
PointerEvent::Button(button_event) => {
|
PointerEvent::Button(button_event) => {
|
||||||
trace!(
|
trace!(self.logger, "Calling on_pointer_button with {:?}", button_event);
|
||||||
self.logger,
|
|
||||||
"Calling on_pointer_button with {:?}",
|
|
||||||
button_event
|
|
||||||
);
|
|
||||||
handler.on_pointer_button(seat, button_event);
|
handler.on_pointer_button(seat, button_event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -606,13 +593,10 @@ pub fn libinput_bind<Data: 'static>(
|
||||||
) -> ::std::result::Result<Source<Generic<EventedRawFd>>, IoError> {
|
) -> ::std::result::Result<Source<Generic<EventedRawFd>>, IoError> {
|
||||||
let mut source = Generic::from_raw_fd(unsafe { backend.context.fd() });
|
let mut source = Generic::from_raw_fd(unsafe { backend.context.fd() });
|
||||||
source.set_interest(Ready::readable());
|
source.set_interest(Ready::readable());
|
||||||
handle.insert_source(
|
handle.insert_source(source, move |_, _| {
|
||||||
source,
|
use backend::input::InputBackend;
|
||||||
move |_, _| {
|
if let Err(error) = backend.dispatch_new_events() {
|
||||||
use backend::input::InputBackend;
|
warn!(backend.logger, "Libinput errored: {}", error);
|
||||||
if let Err(error) = backend.dispatch_new_events() {
|
|
||||||
warn!(backend.logger, "Libinput errored: {}", error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,9 @@
|
||||||
//! - winit
|
//! - winit
|
||||||
//! - libinput
|
//! - libinput
|
||||||
|
|
||||||
pub mod input;
|
|
||||||
pub mod graphics;
|
pub mod graphics;
|
||||||
|
pub mod input;
|
||||||
|
|
||||||
#[cfg(feature = "backend_winit")]
|
|
||||||
pub mod winit;
|
|
||||||
#[cfg(feature = "backend_drm")]
|
#[cfg(feature = "backend_drm")]
|
||||||
pub mod drm;
|
pub mod drm;
|
||||||
#[cfg(feature = "backend_libinput")]
|
#[cfg(feature = "backend_libinput")]
|
||||||
|
@ -27,3 +25,5 @@ pub mod libinput;
|
||||||
pub mod session;
|
pub mod session;
|
||||||
#[cfg(feature = "backend_udev")]
|
#[cfg(feature = "backend_udev")]
|
||||||
pub mod udev;
|
pub mod udev;
|
||||||
|
#[cfg(feature = "backend_winit")]
|
||||||
|
pub mod winit;
|
||||||
|
|
|
@ -28,10 +28,10 @@
|
||||||
//! automatically by the `UdevBackend`, if not done manually).
|
//! automatically by the `UdevBackend`, if not done manually).
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use super::{AsErrno, AsSessionObserver, Session, SessionNotifier, SessionObserver};
|
use super::direct::{self, direct_session_bind, BoundDirectSession, DirectSession, DirectSessionNotifier};
|
||||||
use super::direct::{self, direct_session_bind, DirectSession, DirectSessionNotifier, BoundDirectSession};
|
|
||||||
#[cfg(feature = "backend_session_logind")]
|
#[cfg(feature = "backend_session_logind")]
|
||||||
use super::logind::{self, logind_session_bind, BoundLogindSession, LogindSession, LogindSessionNotifier};
|
use super::logind::{self, logind_session_bind, BoundLogindSession, LogindSession, LogindSessionNotifier};
|
||||||
|
use super::{AsErrno, AsSessionObserver, Session, SessionNotifier, SessionObserver};
|
||||||
use nix::fcntl::OFlag;
|
use nix::fcntl::OFlag;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::io::Error as IoError;
|
use std::io::Error as IoError;
|
||||||
|
@ -109,10 +109,7 @@ impl AutoSession {
|
||||||
)),
|
)),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!(logger, "Failed to create direct session: {}", err);
|
warn!(logger, "Failed to create direct session: {}", err);
|
||||||
error!(
|
error!(logger, "Could not create any session, possibilities exhausted");
|
||||||
logger,
|
|
||||||
"Could not create any session, possibilities exhausted"
|
|
||||||
);
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,10 +133,7 @@ impl AutoSession {
|
||||||
)),
|
)),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!(logger, "Failed to create direct session: {}", err);
|
warn!(logger, "Failed to create direct session: {}", err);
|
||||||
error!(
|
error!(logger, "Could not create any session, possibilities exhausted");
|
||||||
logger,
|
|
||||||
"Could not create any session, possibilities exhausted"
|
|
||||||
);
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,7 +249,7 @@ impl BoundAutoSession {
|
||||||
match self {
|
match self {
|
||||||
#[cfg(feature = "backend_session_logind")]
|
#[cfg(feature = "backend_session_logind")]
|
||||||
BoundAutoSession::Logind(logind) => AutoSessionNotifier::Logind(logind.unbind()),
|
BoundAutoSession::Logind(logind) => AutoSessionNotifier::Logind(logind.unbind()),
|
||||||
BoundAutoSession::Direct(direct) => AutoSessionNotifier::Direct(direct.unbind())
|
BoundAutoSession::Direct(direct) => AutoSessionNotifier::Direct(direct.unbind()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,10 @@
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use backend::session::{AsErrno, AsSessionObserver, Session, SessionNotifier, SessionObserver};
|
use backend::session::{AsErrno, AsSessionObserver, Session, SessionNotifier, SessionObserver};
|
||||||
use dbus::{BusName, BusType, Connection, ConnectionItem, ConnectionItems, Interface, Member, Message,
|
use dbus::{
|
||||||
MessageItem, OwnedFd, Path as DbusPath, Watch, WatchEvent};
|
BusName, BusType, Connection, ConnectionItem, ConnectionItems, Interface, Member, Message, MessageItem,
|
||||||
|
OwnedFd, Path as DbusPath, Watch, WatchEvent,
|
||||||
|
};
|
||||||
use nix::fcntl::OFlag;
|
use nix::fcntl::OFlag;
|
||||||
use nix::sys::stat::{fstat, major, minor, stat};
|
use nix::sys::stat::{fstat, major, minor, stat};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
@ -43,8 +45,8 @@ use std::rc::{Rc, Weak};
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use systemd::login;
|
use systemd::login;
|
||||||
|
|
||||||
use wayland_server::calloop::{Loophandle, Source, Ready};
|
use wayland_server::calloop::generic::{Event, EventedRawFd, Generic};
|
||||||
use wayland_server::calloop::generic::{Generic, EventedRawFd, Event};
|
use wayland_server::calloop::{Loophandle, Ready, Source};
|
||||||
|
|
||||||
struct LogindSessionImpl {
|
struct LogindSessionImpl {
|
||||||
conn: RefCell<Connection>,
|
conn: RefCell<Connection>,
|
||||||
|
@ -93,7 +95,7 @@ impl LogindSession {
|
||||||
"GetSession",
|
"GetSession",
|
||||||
Some(vec![session_id.clone().into()]),
|
Some(vec![session_id.clone().into()]),
|
||||||
)?.get1::<DbusPath<'static>>()
|
)?.get1::<DbusPath<'static>>()
|
||||||
.chain_err(|| ErrorKind::UnexpectedMethodReturn)?;
|
.chain_err(|| ErrorKind::UnexpectedMethodReturn)?;
|
||||||
|
|
||||||
// Match all signals that we want to receive and handle
|
// Match all signals that we want to receive and handle
|
||||||
let match1 = String::from(
|
let match1 = String::from(
|
||||||
|
@ -212,15 +214,14 @@ impl LogindSessionImpl {
|
||||||
message.append_items(&arguments)
|
message.append_items(&arguments)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut message = conn.send_with_reply_and_block(message, 1000)
|
let mut message = conn.send_with_reply_and_block(message, 1000).chain_err(|| {
|
||||||
.chain_err(|| {
|
ErrorKind::FailedToSendDbusCall(
|
||||||
ErrorKind::FailedToSendDbusCall(
|
destination.clone(),
|
||||||
destination.clone(),
|
path.clone(),
|
||||||
path.clone(),
|
interface.clone(),
|
||||||
interface.clone(),
|
method.clone(),
|
||||||
method.clone(),
|
)
|
||||||
)
|
})?;
|
||||||
})?;
|
|
||||||
|
|
||||||
match message.as_result() {
|
match message.as_result() {
|
||||||
Ok(_) => Ok(message),
|
Ok(_) => Ok(message),
|
||||||
|
@ -290,8 +291,7 @@ impl LogindSessionImpl {
|
||||||
let (major, minor, fd) = message.get3::<u32, u32, OwnedFd>();
|
let (major, minor, fd) = message.get3::<u32, u32, OwnedFd>();
|
||||||
let major = major.chain_err(|| ErrorKind::UnexpectedMethodReturn)?;
|
let major = major.chain_err(|| ErrorKind::UnexpectedMethodReturn)?;
|
||||||
let minor = minor.chain_err(|| ErrorKind::UnexpectedMethodReturn)?;
|
let minor = minor.chain_err(|| ErrorKind::UnexpectedMethodReturn)?;
|
||||||
let fd = fd.chain_err(|| ErrorKind::UnexpectedMethodReturn)?
|
let fd = fd.chain_err(|| ErrorKind::UnexpectedMethodReturn)?.into_fd();
|
||||||
.into_fd();
|
|
||||||
debug!(self.logger, "Reactivating device ({},{})", major, minor);
|
debug!(self.logger, "Reactivating device ({},{})", major, minor);
|
||||||
for signal in &mut *self.signals.borrow_mut() {
|
for signal in &mut *self.signals.borrow_mut() {
|
||||||
if let &mut Some(ref mut signal) = signal {
|
if let &mut Some(ref mut signal) = signal {
|
||||||
|
@ -336,8 +336,7 @@ impl Session for LogindSession {
|
||||||
(minor(stat.st_rdev) as u32).into(),
|
(minor(stat.st_rdev) as u32).into(),
|
||||||
]),
|
]),
|
||||||
)?.get2::<OwnedFd, bool>();
|
)?.get2::<OwnedFd, bool>();
|
||||||
let fd = fd.chain_err(|| ErrorKind::UnexpectedMethodReturn)?
|
let fd = fd.chain_err(|| ErrorKind::UnexpectedMethodReturn)?.into_fd();
|
||||||
.into_fd();
|
|
||||||
Ok(fd)
|
Ok(fd)
|
||||||
} else {
|
} else {
|
||||||
bail!(ErrorKind::SessionLost)
|
bail!(ErrorKind::SessionLost)
|
||||||
|
@ -510,8 +509,8 @@ impl LogindSessionNotifier {
|
||||||
} else if readiness.writable() {
|
} else if readiness.writable() {
|
||||||
WatchEvent::Writable as u32
|
WatchEvent::Writable as u32
|
||||||
} else {
|
} else {
|
||||||
return
|
return;
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
if let Err(err) = self.internal.handle_signals(items) {
|
if let Err(err) = self.internal.handle_signals(items) {
|
||||||
error!(self.internal.logger, "Error handling dbus signals: {}", err);
|
error!(self.internal.logger, "Error handling dbus signals: {}", err);
|
||||||
|
|
|
@ -46,23 +46,23 @@
|
||||||
//! automatically by the `UdevBackend`, if not done manually).
|
//! automatically by the `UdevBackend`, if not done manually).
|
||||||
|
|
||||||
use super::{AsErrno, AsSessionObserver, Session, SessionNotifier, SessionObserver};
|
use super::{AsErrno, AsSessionObserver, Session, SessionNotifier, SessionObserver};
|
||||||
use nix::{Error as NixError, Result as NixResult};
|
|
||||||
use nix::fcntl::{self, open, OFlag};
|
use nix::fcntl::{self, open, OFlag};
|
||||||
use nix::libc::c_int;
|
use nix::libc::c_int;
|
||||||
use nix::sys::signal::{self, Signal};
|
use nix::sys::signal::{self, Signal};
|
||||||
use nix::sys::stat::{dev_t, fstat, major, minor, Mode};
|
use nix::sys::stat::{dev_t, fstat, major, minor, Mode};
|
||||||
use nix::unistd::{close, dup};
|
use nix::unistd::{close, dup};
|
||||||
|
use nix::{Error as NixError, Result as NixResult};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
|
||||||
use std::io::Error as IoError;
|
use std::io::Error as IoError;
|
||||||
use std::os::unix::io::RawFd;
|
use std::os::unix::io::RawFd;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::Arc;
|
use std::rc::Rc;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use std::sync::Arc;
|
||||||
#[cfg(feature = "backend_session_udev")]
|
#[cfg(feature = "backend_session_udev")]
|
||||||
use udev::Context;
|
use udev::Context;
|
||||||
use wayland_server::calloop::{LoopHandle, Source};
|
|
||||||
use wayland_server::calloop::signals::Signals;
|
use wayland_server::calloop::signals::Signals;
|
||||||
|
use wayland_server::calloop::{LoopHandle, Source};
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
mod tty {
|
mod tty {
|
||||||
|
@ -172,13 +172,16 @@ impl DirectSession {
|
||||||
let logger = ::slog_or_stdlog(logger)
|
let logger = ::slog_or_stdlog(logger)
|
||||||
.new(o!("smithay_module" => "backend_session", "session_type" => "direct/vt"));
|
.new(o!("smithay_module" => "backend_session", "session_type" => "direct/vt"));
|
||||||
|
|
||||||
let fd = tty.map(|path| {
|
let fd = tty
|
||||||
open(
|
.map(|path| {
|
||||||
path,
|
open(
|
||||||
fcntl::OFlag::O_RDWR | fcntl::OFlag::O_CLOEXEC,
|
path,
|
||||||
Mode::empty(),
|
fcntl::OFlag::O_RDWR | fcntl::OFlag::O_CLOEXEC,
|
||||||
).chain_err(|| ErrorKind::FailedToOpenTTY(String::from(path.to_string_lossy())))
|
Mode::empty(),
|
||||||
}).unwrap_or_else(|| dup(0 /*stdin*/).chain_err(|| ErrorKind::FailedToOpenTTY(String::from("<stdin>"))))?;
|
).chain_err(|| ErrorKind::FailedToOpenTTY(String::from(path.to_string_lossy())))
|
||||||
|
}).unwrap_or_else(|| {
|
||||||
|
dup(0 /*stdin*/).chain_err(|| ErrorKind::FailedToOpenTTY(String::from("<stdin>")))
|
||||||
|
})?;
|
||||||
|
|
||||||
let active = Arc::new(AtomicBool::new(true));
|
let active = Arc::new(AtomicBool::new(true));
|
||||||
|
|
||||||
|
@ -311,16 +314,10 @@ impl Drop for DirectSession {
|
||||||
info!(self.logger, "Deallocating tty {}", self.tty);
|
info!(self.logger, "Deallocating tty {}", self.tty);
|
||||||
|
|
||||||
if let Err(err) = unsafe { tty::kd_set_kb_mode(self.tty, self.old_keyboard_mode) } {
|
if let Err(err) = unsafe { tty::kd_set_kb_mode(self.tty, self.old_keyboard_mode) } {
|
||||||
warn!(
|
warn!(self.logger, "Unable to restore vt keyboard mode. Error: {}", err);
|
||||||
self.logger,
|
|
||||||
"Unable to restore vt keyboard mode. Error: {}", err
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if let Err(err) = unsafe { tty::kd_set_mode(self.tty, tty::KD_TEXT as i32) } {
|
if let Err(err) = unsafe { tty::kd_set_mode(self.tty, tty::KD_TEXT as i32) } {
|
||||||
warn!(
|
warn!(self.logger, "Unable to restore vt text mode. Error: {}", err);
|
||||||
self.logger,
|
|
||||||
"Unable to restore vt text mode. Error: {}", err
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if let Err(err) = unsafe {
|
if let Err(err) = unsafe {
|
||||||
tty::vt_set_mode(
|
tty::vt_set_mode(
|
||||||
|
@ -334,10 +331,7 @@ impl Drop for DirectSession {
|
||||||
error!(self.logger, "Failed to reset vt handling. Error: {}", err);
|
error!(self.logger, "Failed to reset vt handling. Error: {}", err);
|
||||||
}
|
}
|
||||||
if let Err(err) = close(self.tty) {
|
if let Err(err) = close(self.tty) {
|
||||||
error!(
|
error!(self.logger, "Failed to close tty file descriptor. Error: {}", err);
|
||||||
self.logger,
|
|
||||||
"Failed to close tty file descriptor. Error: {}", err
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -403,7 +397,7 @@ impl DirectSessionNotifier {
|
||||||
/// See `direct_session_bind` for details.
|
/// See `direct_session_bind` for details.
|
||||||
pub struct BoundDirectSession {
|
pub struct BoundDirectSession {
|
||||||
source: Source<Signals>,
|
source: Source<Signals>,
|
||||||
notifier: Rc<RefCell<DirectSessionNotifier>>
|
notifier: Rc<RefCell<DirectSessionNotifier>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BoundDirectSession {
|
impl BoundDirectSession {
|
||||||
|
@ -413,7 +407,7 @@ impl BoundDirectSession {
|
||||||
source.remove();
|
source.remove();
|
||||||
match Rc::try_unwrap(notifier) {
|
match Rc::try_unwrap(notifier) {
|
||||||
Ok(notifier) => notifier.into_inner(),
|
Ok(notifier) => notifier.into_inner(),
|
||||||
Err(_) => panic!("Notifier should have been freed from the event loop!")
|
Err(_) => panic!("Notifier should have been freed from the event loop!"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -429,16 +423,11 @@ pub fn direct_session_bind<Data: 'static>(
|
||||||
) -> ::std::result::Result<BoundDirectSession, IoError> {
|
) -> ::std::result::Result<BoundDirectSession, IoError> {
|
||||||
let signal = notifier.signal;
|
let signal = notifier.signal;
|
||||||
let notifier = Rc::new(RefCell::new(notifier));
|
let notifier = Rc::new(RefCell::new(notifier));
|
||||||
let source = handle.insert_source(
|
let source = handle.insert_source(Signals::new(&[signal])?, {
|
||||||
Signals::new(&[signal])?,
|
let notifier = notifier.clone();
|
||||||
{
|
move |_, _| notifier.borrow_mut().signal_received()
|
||||||
let notifier = notifier.clone();
|
})?;
|
||||||
move |_, _| notifier.borrow_mut().signal_received()
|
Ok(BoundDirectSession { source, notifier })
|
||||||
}
|
|
||||||
)?;
|
|
||||||
Ok(BoundDirectSession {
|
|
||||||
source, notifier
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error_chain! {
|
error_chain! {
|
||||||
|
|
|
@ -181,6 +181,6 @@ impl AsErrno for () {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod auto;
|
pub mod auto;
|
||||||
pub mod direct;
|
|
||||||
mod dbus;
|
mod dbus;
|
||||||
|
pub mod direct;
|
||||||
pub use self::dbus::*;
|
pub use self::dbus::*;
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
|
|
||||||
use backend::drm::{drm_device_bind, DrmDevice, DrmHandler};
|
use backend::drm::{drm_device_bind, DrmDevice, DrmHandler};
|
||||||
use backend::session::{AsSessionObserver, Session, SessionObserver};
|
use backend::session::{AsSessionObserver, Session, SessionObserver};
|
||||||
use drm::Device as BasicDevice;
|
|
||||||
use drm::control::Device as ControlDevice;
|
use drm::control::Device as ControlDevice;
|
||||||
|
use drm::Device as BasicDevice;
|
||||||
use nix::fcntl;
|
use nix::fcntl;
|
||||||
use nix::sys::stat::dev_t;
|
use nix::sys::stat::dev_t;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
@ -25,8 +25,8 @@ use std::path::{Path, PathBuf};
|
||||||
use std::rc::{Rc, Weak};
|
use std::rc::{Rc, Weak};
|
||||||
use udev::{Context, Enumerator, Event, EventType, MonitorBuilder, MonitorSocket, Result as UdevResult};
|
use udev::{Context, Enumerator, Event, EventType, MonitorBuilder, MonitorSocket, Result as UdevResult};
|
||||||
|
|
||||||
use wayland_server::calloop::{LoopHandle, Source, Ready};
|
use wayland_server::calloop::generic::{EventedRawFd, Generic};
|
||||||
use wayland_server::calloop::generic::{Generic, EventedRawFd};
|
use wayland_server::calloop::{LoopHandle, Ready, Source};
|
||||||
|
|
||||||
/// Udev's `DrmDevice` type based on the underlying session
|
/// Udev's `DrmDevice` type based on the underlying session
|
||||||
pub struct SessionFdDrmDevice(RawFd);
|
pub struct SessionFdDrmDevice(RawFd);
|
||||||
|
@ -48,10 +48,20 @@ pub struct UdevBackend<
|
||||||
H: DrmHandler<SessionFdDrmDevice> + 'static,
|
H: DrmHandler<SessionFdDrmDevice> + 'static,
|
||||||
S: Session + 'static,
|
S: Session + 'static,
|
||||||
T: UdevHandler<H> + 'static,
|
T: UdevHandler<H> + 'static,
|
||||||
Data: 'static
|
Data: 'static,
|
||||||
> {
|
> {
|
||||||
_handler: ::std::marker::PhantomData<H>,
|
_handler: ::std::marker::PhantomData<H>,
|
||||||
devices: Rc<RefCell<HashMap<dev_t, (Source<Generic<EventedRawFd>>, Rc<RefCell<DrmDevice<SessionFdDrmDevice>>>)>>>,
|
devices: Rc<
|
||||||
|
RefCell<
|
||||||
|
HashMap<
|
||||||
|
dev_t,
|
||||||
|
(
|
||||||
|
Source<Generic<EventedRawFd>>,
|
||||||
|
Rc<RefCell<DrmDevice<SessionFdDrmDevice>>>,
|
||||||
|
),
|
||||||
|
>,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
monitor: MonitorSocket,
|
monitor: MonitorSocket,
|
||||||
session: S,
|
session: S,
|
||||||
handler: T,
|
handler: T,
|
||||||
|
@ -59,8 +69,12 @@ pub struct UdevBackend<
|
||||||
handle: LoopHandle<Data>,
|
handle: LoopHandle<Data>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H: DrmHandler<SessionFdDrmDevice> + 'static, S: Session + 'static, T: UdevHandler<H> + 'static, Data: 'static>
|
impl<
|
||||||
UdevBackend<H, S, T, Data>
|
H: DrmHandler<SessionFdDrmDevice> + 'static,
|
||||||
|
S: Session + 'static,
|
||||||
|
T: UdevHandler<H> + 'static,
|
||||||
|
Data: 'static,
|
||||||
|
> UdevBackend<H, S, T, Data>
|
||||||
{
|
{
|
||||||
/// Creates a new `UdevBackend` and adds it to the given `EventLoop`'s state.
|
/// Creates a new `UdevBackend` and adds it to the given `EventLoop`'s state.
|
||||||
///
|
///
|
||||||
|
@ -138,9 +152,7 @@ impl<H: DrmHandler<SessionFdDrmDevice> + 'static, S: Session + 'static, T: UdevH
|
||||||
builder
|
builder
|
||||||
.match_subsystem("drm")
|
.match_subsystem("drm")
|
||||||
.chain_err(|| ErrorKind::FailedToInitMonitor)?;
|
.chain_err(|| ErrorKind::FailedToInitMonitor)?;
|
||||||
let monitor = builder
|
let monitor = builder.listen().chain_err(|| ErrorKind::FailedToInitMonitor)?;
|
||||||
.listen()
|
|
||||||
.chain_err(|| ErrorKind::FailedToInitMonitor)?;
|
|
||||||
|
|
||||||
Ok(UdevBackend {
|
Ok(UdevBackend {
|
||||||
_handler: ::std::marker::PhantomData,
|
_handler: ::std::marker::PhantomData,
|
||||||
|
@ -165,10 +177,7 @@ impl<H: DrmHandler<SessionFdDrmDevice> + 'static, S: Session + 'static, T: UdevH
|
||||||
let fd = device.as_raw_fd();
|
let fd = device.as_raw_fd();
|
||||||
drop(device);
|
drop(device);
|
||||||
if let Err(err) = self.session.close(fd) {
|
if let Err(err) = self.session.close(fd) {
|
||||||
warn!(
|
warn!(self.logger, "Failed to close device. Error: {:?}. Ignoring", err);
|
||||||
self.logger,
|
|
||||||
"Failed to close device. Error: {:?}. Ignoring", err
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
info!(self.logger, "All devices closed");
|
info!(self.logger, "All devices closed");
|
||||||
|
@ -176,11 +185,12 @@ impl<H: DrmHandler<SessionFdDrmDevice> + 'static, S: Session + 'static, T: UdevH
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
H: DrmHandler<SessionFdDrmDevice> + 'static,
|
H: DrmHandler<SessionFdDrmDevice> + 'static,
|
||||||
S: Session + 'static,
|
S: Session + 'static,
|
||||||
T: UdevHandler<H> + 'static,
|
T: UdevHandler<H> + 'static,
|
||||||
Data: 'static,
|
Data: 'static,
|
||||||
> Drop for UdevBackend<H, S, T, Data> {
|
> Drop for UdevBackend<H, S, T, Data>
|
||||||
|
{
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.close();
|
self.close();
|
||||||
}
|
}
|
||||||
|
@ -188,16 +198,26 @@ impl<
|
||||||
|
|
||||||
/// `SessionObserver` linked to the `UdevBackend` it was created from.
|
/// `SessionObserver` linked to the `UdevBackend` it was created from.
|
||||||
pub struct UdevBackendObserver {
|
pub struct UdevBackendObserver {
|
||||||
devices: Weak<RefCell<HashMap<dev_t, (Source<Generic<EventedRawFd>>, Rc<RefCell<DrmDevice<SessionFdDrmDevice>>>)>>>,
|
devices: Weak<
|
||||||
|
RefCell<
|
||||||
|
HashMap<
|
||||||
|
dev_t,
|
||||||
|
(
|
||||||
|
Source<Generic<EventedRawFd>>,
|
||||||
|
Rc<RefCell<DrmDevice<SessionFdDrmDevice>>>,
|
||||||
|
),
|
||||||
|
>,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
logger: ::slog::Logger,
|
logger: ::slog::Logger,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
H: DrmHandler<SessionFdDrmDevice> + 'static,
|
H: DrmHandler<SessionFdDrmDevice> + 'static,
|
||||||
S: Session + 'static,
|
S: Session + 'static,
|
||||||
T: UdevHandler<H> + 'static,
|
T: UdevHandler<H> + 'static,
|
||||||
Data: 'static,
|
Data: 'static,
|
||||||
> AsSessionObserver<UdevBackendObserver> for UdevBackend<H, S, T, Data>
|
> AsSessionObserver<UdevBackendObserver> for UdevBackend<H, S, T, Data>
|
||||||
{
|
{
|
||||||
fn observer(&mut self) -> UdevBackendObserver {
|
fn observer(&mut self) -> UdevBackendObserver {
|
||||||
UdevBackendObserver {
|
UdevBackendObserver {
|
||||||
|
@ -243,12 +263,9 @@ where
|
||||||
let handle = udev.handle.clone();
|
let handle = udev.handle.clone();
|
||||||
let mut source = Generic::from_raw_fd(fd);
|
let mut source = Generic::from_raw_fd(fd);
|
||||||
source.set_interest(Ready::readable());
|
source.set_interest(Ready::readable());
|
||||||
handle.insert_source(
|
handle.insert_source(source, move |_, _| {
|
||||||
source,
|
udev.process_events();
|
||||||
move |_, _| {
|
})
|
||||||
udev.process_events();
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<H, S, T, Data> UdevBackend<H, S, T, Data>
|
impl<H, S, T, Data> UdevBackend<H, S, T, Data>
|
||||||
|
@ -256,7 +273,7 @@ where
|
||||||
H: DrmHandler<SessionFdDrmDevice> + 'static,
|
H: DrmHandler<SessionFdDrmDevice> + 'static,
|
||||||
T: UdevHandler<H> + 'static,
|
T: UdevHandler<H> + 'static,
|
||||||
S: Session + 'static,
|
S: Session + 'static,
|
||||||
Data: 'static
|
Data: 'static,
|
||||||
{
|
{
|
||||||
fn process_events(&mut self) {
|
fn process_events(&mut self) {
|
||||||
let events = self.monitor.clone().collect::<Vec<Event>>();
|
let events = self.monitor.clone().collect::<Vec<Event>>();
|
||||||
|
@ -272,7 +289,8 @@ where
|
||||||
let logger = self.logger.clone();
|
let logger = self.logger.clone();
|
||||||
match self.session.open(
|
match self.session.open(
|
||||||
path,
|
path,
|
||||||
fcntl::OFlag::O_RDWR | fcntl::OFlag::O_CLOEXEC
|
fcntl::OFlag::O_RDWR
|
||||||
|
| fcntl::OFlag::O_CLOEXEC
|
||||||
| fcntl::OFlag::O_NOCTTY
|
| fcntl::OFlag::O_NOCTTY
|
||||||
| fcntl::OFlag::O_NONBLOCK,
|
| fcntl::OFlag::O_NONBLOCK,
|
||||||
) {
|
) {
|
||||||
|
@ -294,9 +312,7 @@ where
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!(
|
warn!(
|
||||||
self.logger,
|
self.logger,
|
||||||
"Failed to initialize device {:?}. Error: {}. Skipping",
|
"Failed to initialize device {:?}. Error: {}. Skipping", path, err
|
||||||
path,
|
|
||||||
err
|
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -304,35 +320,27 @@ where
|
||||||
};
|
};
|
||||||
let fd = device.as_raw_fd();
|
let fd = device.as_raw_fd();
|
||||||
match self.handler.device_added(&mut device) {
|
match self.handler.device_added(&mut device) {
|
||||||
Some(drm_handler) => {
|
Some(drm_handler) => match drm_device_bind(&self.handle, device, drm_handler) {
|
||||||
match drm_device_bind(&self.handle, device, drm_handler) {
|
Ok(fd_event_source) => {
|
||||||
Ok(fd_event_source) => {
|
self.devices.borrow_mut().insert(devnum, fd_event_source);
|
||||||
self.devices.borrow_mut().insert(devnum, fd_event_source);
|
}
|
||||||
}
|
Err((err, mut device)) => {
|
||||||
Err((err, mut device)) => {
|
warn!(self.logger, "Failed to bind device. Error: {:?}.", err);
|
||||||
|
self.handler.device_removed(&mut device);
|
||||||
|
drop(device);
|
||||||
|
if let Err(err) = self.session.close(fd) {
|
||||||
warn!(
|
warn!(
|
||||||
self.logger,
|
|
||||||
"Failed to bind device. Error: {:?}.", err
|
|
||||||
);
|
|
||||||
self.handler.device_removed(&mut device);
|
|
||||||
drop(device);
|
|
||||||
if let Err(err) = self.session.close(fd) {
|
|
||||||
warn!(
|
|
||||||
self.logger,
|
self.logger,
|
||||||
"Failed to close dropped device. Error: {:?}. Ignoring", err
|
"Failed to close dropped device. Error: {:?}. Ignoring", err
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
None => {
|
None => {
|
||||||
self.handler.device_removed(&mut device);
|
self.handler.device_removed(&mut device);
|
||||||
drop(device);
|
drop(device);
|
||||||
if let Err(err) = self.session.close(fd) {
|
if let Err(err) = self.session.close(fd) {
|
||||||
warn!(
|
warn!(self.logger, "Failed to close unused device. Error: {:?}", err);
|
||||||
self.logger,
|
|
||||||
"Failed to close unused device. Error: {:?}", err
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -342,9 +350,7 @@ where
|
||||||
EventType::Remove => {
|
EventType::Remove => {
|
||||||
info!(self.logger, "Device Remove");
|
info!(self.logger, "Device Remove");
|
||||||
if let Some(devnum) = event.devnum() {
|
if let Some(devnum) = event.devnum() {
|
||||||
if let Some((fd_event_source, device)) =
|
if let Some((fd_event_source, device)) = self.devices.borrow_mut().remove(&devnum) {
|
||||||
self.devices.borrow_mut().remove(&devnum)
|
|
||||||
{
|
|
||||||
fd_event_source.remove();
|
fd_event_source.remove();
|
||||||
let mut device = Rc::try_unwrap(device)
|
let mut device = Rc::try_unwrap(device)
|
||||||
.unwrap_or_else(|_| unreachable!())
|
.unwrap_or_else(|_| unreachable!())
|
||||||
|
@ -429,7 +435,8 @@ pub fn primary_gpu<S: AsRef<str>>(context: &Context, seat: S) -> UdevResult<Opti
|
||||||
if device
|
if device
|
||||||
.property_value("ID_SEAT")
|
.property_value("ID_SEAT")
|
||||||
.map(|x| x.to_os_string())
|
.map(|x| x.to_os_string())
|
||||||
.unwrap_or(OsString::from("seat0")) == *seat.as_ref()
|
.unwrap_or(OsString::from("seat0"))
|
||||||
|
== *seat.as_ref()
|
||||||
{
|
{
|
||||||
if let Some(pci) = device.parent_with_subsystem(Path::new("pci"))? {
|
if let Some(pci) = device.parent_with_subsystem(Path::new("pci"))? {
|
||||||
if let Some(id) = pci.attribute_value("boot_vga") {
|
if let Some(id) = pci.attribute_value("boot_vga") {
|
||||||
|
@ -458,9 +465,9 @@ pub fn all_gpus<S: AsRef<str>>(context: &Context, seat: S) -> UdevResult<Vec<Pat
|
||||||
device
|
device
|
||||||
.property_value("ID_SEAT")
|
.property_value("ID_SEAT")
|
||||||
.map(|x| x.to_os_string())
|
.map(|x| x.to_os_string())
|
||||||
.unwrap_or(OsString::from("seat0")) == *seat.as_ref()
|
.unwrap_or(OsString::from("seat0"))
|
||||||
})
|
== *seat.as_ref()
|
||||||
.flat_map(|device| device.devnode().map(PathBuf::from))
|
}).flat_map(|device| device.devnode().map(PathBuf::from))
|
||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
//! Implementation of backend traits for types provided by `winit`
|
//! Implementation of backend traits for types provided by `winit`
|
||||||
|
|
||||||
use backend::graphics::GraphicsBackend;
|
|
||||||
use backend::graphics::egl::{EGLContext, EGLGraphicsBackend, EGLSurface, PixelFormat, SwapBuffersError};
|
|
||||||
use backend::graphics::egl::context::GlAttributes;
|
use backend::graphics::egl::context::GlAttributes;
|
||||||
use backend::graphics::egl::error as egl_error;
|
use backend::graphics::egl::error as egl_error;
|
||||||
use backend::graphics::egl::error::Result as EGLResult;
|
use backend::graphics::egl::error::Result as EGLResult;
|
||||||
use backend::graphics::egl::native;
|
use backend::graphics::egl::native;
|
||||||
use backend::graphics::egl::wayland::{EGLDisplay, EGLWaylandExtensions};
|
use backend::graphics::egl::wayland::{EGLDisplay, EGLWaylandExtensions};
|
||||||
use backend::input::{Axis, AxisSource, Event as BackendEvent, InputBackend, InputHandler, KeyState,
|
use backend::graphics::egl::{EGLContext, EGLGraphicsBackend, EGLSurface, PixelFormat, SwapBuffersError};
|
||||||
KeyboardKeyEvent, MouseButton, MouseButtonState, PointerAxisEvent, PointerButtonEvent,
|
use backend::graphics::GraphicsBackend;
|
||||||
PointerMotionAbsoluteEvent, Seat, SeatCapabilities, TouchCancelEvent, TouchDownEvent,
|
use backend::input::{
|
||||||
TouchMotionEvent, TouchSlot, TouchUpEvent, UnusedEvent};
|
Axis, AxisSource, Event as BackendEvent, InputBackend, InputHandler, KeyState, KeyboardKeyEvent,
|
||||||
|
MouseButton, MouseButtonState, PointerAxisEvent, PointerButtonEvent, PointerMotionAbsoluteEvent, Seat,
|
||||||
|
SeatCapabilities, TouchCancelEvent, TouchDownEvent, TouchMotionEvent, TouchSlot, TouchUpEvent,
|
||||||
|
UnusedEvent,
|
||||||
|
};
|
||||||
use nix::libc::c_void;
|
use nix::libc::c_void;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::error;
|
use std::error;
|
||||||
|
@ -19,8 +21,10 @@ use std::rc::Rc;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use wayland_client::egl as wegl;
|
use wayland_client::egl as wegl;
|
||||||
use wayland_server::Display;
|
use wayland_server::Display;
|
||||||
use winit::{ElementState, Event, EventsLoop, KeyboardInput, MouseButton as WinitMouseButton, MouseCursor,
|
use winit::{
|
||||||
MouseScrollDelta, Touch, TouchPhase, Window as WinitWindow, WindowBuilder, WindowEvent};
|
ElementState, Event, EventsLoop, KeyboardInput, MouseButton as WinitMouseButton, MouseCursor,
|
||||||
|
MouseScrollDelta, Touch, TouchPhase, Window as WinitWindow, WindowBuilder, WindowEvent,
|
||||||
|
};
|
||||||
|
|
||||||
error_chain! {
|
error_chain! {
|
||||||
errors {
|
errors {
|
||||||
|
@ -136,9 +140,7 @@ where
|
||||||
info!(log, "Initializing a winit backend");
|
info!(log, "Initializing a winit backend");
|
||||||
|
|
||||||
let events_loop = EventsLoop::new();
|
let events_loop = EventsLoop::new();
|
||||||
let winit_window = builder
|
let winit_window = builder.build(&events_loop).chain_err(|| ErrorKind::InitFailed)?;
|
||||||
.build(&events_loop)
|
|
||||||
.chain_err(|| ErrorKind::InitFailed)?;
|
|
||||||
debug!(log, "Window created");
|
debug!(log, "Window created");
|
||||||
|
|
||||||
let reqs = Default::default();
|
let reqs = Default::default();
|
||||||
|
@ -367,24 +369,16 @@ impl PointerMotionAbsoluteEvent for WinitMouseMovedEvent {
|
||||||
|
|
||||||
fn x_transformed(&self, width: u32) -> u32 {
|
fn x_transformed(&self, width: u32) -> u32 {
|
||||||
cmp::max(
|
cmp::max(
|
||||||
(self.x * width as f64
|
(self.x * width as f64 / self.window.window().get_inner_size().unwrap_or((width, 0)).0 as f64)
|
||||||
/ self.window
|
as i32,
|
||||||
.window()
|
|
||||||
.get_inner_size()
|
|
||||||
.unwrap_or((width, 0))
|
|
||||||
.0 as f64) as i32,
|
|
||||||
0,
|
0,
|
||||||
) as u32
|
) as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
fn y_transformed(&self, height: u32) -> u32 {
|
fn y_transformed(&self, height: u32) -> u32 {
|
||||||
cmp::max(
|
cmp::max(
|
||||||
(self.y * height as f64
|
(self.y * height as f64 / self.window.window().get_inner_size().unwrap_or((0, height)).1 as f64)
|
||||||
/ self.window
|
as i32,
|
||||||
.window()
|
|
||||||
.get_inner_size()
|
|
||||||
.unwrap_or((0, height))
|
|
||||||
.1 as f64) as i32,
|
|
||||||
0,
|
0,
|
||||||
) as u32
|
) as u32
|
||||||
}
|
}
|
||||||
|
@ -483,11 +477,7 @@ impl TouchDownEvent for WinitTouchStartedEvent {
|
||||||
fn x_transformed(&self, width: u32) -> u32 {
|
fn x_transformed(&self, width: u32) -> u32 {
|
||||||
cmp::min(
|
cmp::min(
|
||||||
self.location.0 as i32 * width as i32
|
self.location.0 as i32 * width as i32
|
||||||
/ self.window
|
/ self.window.window().get_inner_size().unwrap_or((width, 0)).0 as i32,
|
||||||
.window()
|
|
||||||
.get_inner_size()
|
|
||||||
.unwrap_or((width, 0))
|
|
||||||
.0 as i32,
|
|
||||||
0,
|
0,
|
||||||
) as u32
|
) as u32
|
||||||
}
|
}
|
||||||
|
@ -495,11 +485,7 @@ impl TouchDownEvent for WinitTouchStartedEvent {
|
||||||
fn y_transformed(&self, height: u32) -> u32 {
|
fn y_transformed(&self, height: u32) -> u32 {
|
||||||
cmp::min(
|
cmp::min(
|
||||||
self.location.1 as i32 * height as i32
|
self.location.1 as i32 * height as i32
|
||||||
/ self.window
|
/ self.window.window().get_inner_size().unwrap_or((0, height)).1 as i32,
|
||||||
.window()
|
|
||||||
.get_inner_size()
|
|
||||||
.unwrap_or((0, height))
|
|
||||||
.1 as i32,
|
|
||||||
0,
|
0,
|
||||||
) as u32
|
) as u32
|
||||||
}
|
}
|
||||||
|
@ -534,21 +520,11 @@ impl TouchMotionEvent for WinitTouchMovedEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn x_transformed(&self, width: u32) -> u32 {
|
fn x_transformed(&self, width: u32) -> u32 {
|
||||||
self.location.0 as u32 * width
|
self.location.0 as u32 * width / self.window.window().get_inner_size().unwrap_or((width, 0)).0
|
||||||
/ self.window
|
|
||||||
.window()
|
|
||||||
.get_inner_size()
|
|
||||||
.unwrap_or((width, 0))
|
|
||||||
.0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn y_transformed(&self, height: u32) -> u32 {
|
fn y_transformed(&self, height: u32) -> u32 {
|
||||||
self.location.1 as u32 * height
|
self.location.1 as u32 * height / self.window.window().get_inner_size().unwrap_or((0, height)).1
|
||||||
/ self.window
|
|
||||||
.window()
|
|
||||||
.get_inner_size()
|
|
||||||
.unwrap_or((0, height))
|
|
||||||
.1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -644,11 +620,7 @@ impl InputBackend for WinitInputBackend {
|
||||||
|
|
||||||
fn clear_handler(&mut self) {
|
fn clear_handler(&mut self) {
|
||||||
if let Some(mut handler) = self.handler.take() {
|
if let Some(mut handler) = self.handler.take() {
|
||||||
trace!(
|
trace!(self.logger, "Calling on_seat_destroyed with {:?}", self.seat);
|
||||||
self.logger,
|
|
||||||
"Calling on_seat_destroyed with {:?}",
|
|
||||||
self.seat
|
|
||||||
);
|
|
||||||
handler.on_seat_destroyed(&self.seat);
|
handler.on_seat_destroyed(&self.seat);
|
||||||
}
|
}
|
||||||
info!(self.logger, "Removing input handler");
|
info!(self.logger, "Removing input handler");
|
||||||
|
@ -714,10 +686,7 @@ impl InputBackend for WinitInputBackend {
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
WindowEvent::KeyboardInput {
|
WindowEvent::KeyboardInput {
|
||||||
input:
|
input: KeyboardInput { scancode, state, .. },
|
||||||
KeyboardInput {
|
|
||||||
scancode, state, ..
|
|
||||||
},
|
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
Some(handler),
|
Some(handler),
|
||||||
|
@ -729,11 +698,7 @@ impl InputBackend for WinitInputBackend {
|
||||||
*key_counter = key_counter.checked_sub(1).unwrap_or(0)
|
*key_counter = key_counter.checked_sub(1).unwrap_or(0)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
trace!(
|
trace!(logger, "Calling on_keyboard_key with {:?}", (scancode, state));
|
||||||
logger,
|
|
||||||
"Calling on_keyboard_key with {:?}",
|
|
||||||
(scancode, state)
|
|
||||||
);
|
|
||||||
handler.on_keyboard_key(
|
handler.on_keyboard_key(
|
||||||
seat,
|
seat,
|
||||||
WinitKeyboardInputEvent {
|
WinitKeyboardInputEvent {
|
||||||
|
@ -744,13 +709,7 @@ impl InputBackend for WinitInputBackend {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
(
|
(WindowEvent::CursorMoved { position: (x, y), .. }, Some(handler), _) => {
|
||||||
WindowEvent::CursorMoved {
|
|
||||||
position: (x, y), ..
|
|
||||||
},
|
|
||||||
Some(handler),
|
|
||||||
_,
|
|
||||||
) => {
|
|
||||||
trace!(logger, "Calling on_pointer_move_absolute with {:?}", (x, y));
|
trace!(logger, "Calling on_pointer_move_absolute with {:?}", (x, y));
|
||||||
handler.on_pointer_move_absolute(
|
handler.on_pointer_move_absolute(
|
||||||
seat,
|
seat,
|
||||||
|
@ -768,19 +727,8 @@ impl InputBackend for WinitInputBackend {
|
||||||
handler.on_pointer_axis(seat, event);
|
handler.on_pointer_axis(seat, event);
|
||||||
}
|
}
|
||||||
(WindowEvent::MouseInput { state, button, .. }, Some(handler), _) => {
|
(WindowEvent::MouseInput { state, button, .. }, Some(handler), _) => {
|
||||||
trace!(
|
trace!(logger, "Calling on_pointer_button with {:?}", (button, state));
|
||||||
logger,
|
handler.on_pointer_button(seat, WinitMouseInputEvent { time, button, state })
|
||||||
"Calling on_pointer_button with {:?}",
|
|
||||||
(button, state)
|
|
||||||
);
|
|
||||||
handler.on_pointer_button(
|
|
||||||
seat,
|
|
||||||
WinitMouseInputEvent {
|
|
||||||
time,
|
|
||||||
button,
|
|
||||||
state,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
WindowEvent::Touch(Touch {
|
WindowEvent::Touch(Touch {
|
||||||
|
|
|
@ -49,8 +49,8 @@ extern crate error_chain;
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
|
|
||||||
pub mod backend;
|
pub mod backend;
|
||||||
pub mod wayland;
|
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
pub mod wayland;
|
||||||
|
|
||||||
#[cfg(feature = "xwayland")]
|
#[cfg(feature = "xwayland")]
|
||||||
pub mod xwayland;
|
pub mod xwayland;
|
||||||
|
|
|
@ -15,5 +15,5 @@
|
||||||
pub mod compositor;
|
pub mod compositor;
|
||||||
pub mod output;
|
pub mod output;
|
||||||
pub mod seat;
|
pub mod seat;
|
||||||
pub mod shm;
|
|
||||||
pub mod shell;
|
pub mod shell;
|
||||||
|
pub mod shm;
|
||||||
|
|
Loading…
Reference in New Issue