diff --git a/src/backends/metal/monitor.rs b/src/backends/metal/monitor.rs index 0c0472f3..880c2874 100644 --- a/src/backends/metal/monitor.rs +++ b/src/backends/metal/monitor.rs @@ -205,7 +205,7 @@ impl MetalBackend { return; } let master = Rc::new(DrmMaster::new(res.fd.clone())); - let dev = match slf.creat_drm_device(dev, &master) { + let dev = match slf.create_drm_device(dev, &master) { Ok(d) => d, Err(e) => { log::error!("Could not initialize drm device: {}", ErrorFmt(e)); diff --git a/src/backends/metal/video.rs b/src/backends/metal/video.rs index 6dda3c12..454f5740 100644 --- a/src/backends/metal/video.rs +++ b/src/backends/metal/video.rs @@ -17,6 +17,7 @@ use crate::utils::clonecell::CloneCell; use crate::utils::errorfmt::ErrorFmt; use crate::utils::numcell::NumCell; use crate::utils::oserror::OsError; +use crate::utils::syncqueue::SyncQueue; use ahash::{AHashMap, AHashSet}; use bstr::{BString, ByteSlice}; use std::cell::Cell; @@ -24,7 +25,6 @@ use std::ffi::CString; use std::fmt::{Debug, Formatter}; use std::rc::Rc; use uapi::c; -use crate::utils::syncqueue::SyncQueue; pub struct PendingDrmDevice { pub id: DrmId, @@ -405,7 +405,7 @@ impl MutableProperty { } impl MetalBackend { - pub fn creat_drm_device( + pub fn create_drm_device( self: &Rc, pending: PendingDrmDevice, master: &Rc, diff --git a/src/backends/x.rs b/src/backends/x.rs index 6a8d13eb..ef07ae05 100644 --- a/src/backends/x.rs +++ b/src/backends/x.rs @@ -1,5 +1,8 @@ use crate::async_engine::{Phase, SpawnedFuture}; -use crate::backend::{Backend, BackendEvent, InputDevice, InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId, InputEvent, KeyState, Connector, OutputId, ScrollAxis, Mode, ConnectorEvent}; +use crate::backend::{ + Backend, BackendEvent, Connector, ConnectorEvent, InputDevice, InputDeviceAccelProfile, + InputDeviceCapability, InputDeviceId, InputEvent, KeyState, Mode, OutputId, ScrollAxis, +}; use crate::drm::drm::{Drm, DrmError}; use crate::drm::gbm::{GbmDevice, GbmError, GBM_BO_USE_RENDERING}; use crate::drm::{ModifiedFormat, INVALID_MODIFIER}; @@ -12,6 +15,7 @@ use crate::utils::copyhashmap::CopyHashMap; use crate::utils::errorfmt::ErrorFmt; use crate::utils::numcell::NumCell; use crate::utils::queue::AsyncQueue; +use crate::utils::syncqueue::SyncQueue; use crate::wire_xcon::{ ChangeProperty, ChangeWindowAttributes, ConfigureNotify, CreateCursor, CreatePixmap, CreateWindow, CreateWindowValues, DestroyNotify, Dri3Open, Dri3PixmapFromBuffer, @@ -39,7 +43,6 @@ use std::cell::{Cell, RefCell}; use std::collections::VecDeque; use std::rc::Rc; use thiserror::Error; -use crate::utils::syncqueue::SyncQueue; #[derive(Debug, Error)] pub enum XBackendError { diff --git a/src/drm/drm.rs b/src/drm/drm.rs index 37031db3..b231204f 100644 --- a/src/drm/drm.rs +++ b/src/drm/drm.rs @@ -28,11 +28,11 @@ use crate::drm::INVALID_MODIFIER; use crate::utils::errorfmt::ErrorFmt; use crate::utils::stack::Stack; use crate::utils::syncqueue::SyncQueue; +use crate::utils::vec_ext::VecExt; pub use sys::{ drm_mode_modeinfo, DRM_CLIENT_CAP_ATOMIC, DRM_MODE_ATOMIC_ALLOW_MODESET, DRM_MODE_ATOMIC_NONBLOCK, DRM_MODE_PAGE_FLIP_EVENT, }; -use crate::utils::vec_ext::VecExt; #[derive(Debug, Error)] pub enum DrmError { @@ -108,11 +108,15 @@ fn reopen(fd: c::c_int, need_primary: bool) -> Result, DrmError> { if let Ok((fd, _)) = create_lease(fd, &[], c::O_CLOEXEC as _) { return Ok(Rc::new(fd)); } - let path = if get_node_type_from_fd(fd).map_err(DrmError::GetDeviceType)? == NodeType::Render { - uapi::format_ustr!("/proc/self/fd/{}", fd) - } else if !need_primary { - render_node_name(fd)? - } else { + let path = 'path: { + if get_node_type_from_fd(fd).map_err(DrmError::GetDeviceType)? == NodeType::Render { + break 'path uapi::format_ustr!("/proc/self/fd/{}", fd); + } + if !need_primary { + if let Ok(path) = render_node_name(fd) { + break 'path path; + } + } device_node_name(fd)? }; match uapi::open(&path, c::O_RDWR | c::O_CLOEXEC, 0) { diff --git a/src/drm/gbm.rs b/src/drm/gbm.rs index f5efaedb..83d8d31d 100644 --- a/src/drm/gbm.rs +++ b/src/drm/gbm.rs @@ -22,7 +22,7 @@ pub enum GbmError { DrmFd, } -type Device = u8; +pub type Device = u8; type Bo = u8; pub const GBM_BO_USE_SCANOUT: u32 = 1 << 0; @@ -128,6 +128,10 @@ impl GbmDevice { } } + pub fn raw(&self) -> *mut Device { + self.dev + } + pub fn create_bo( &self, width: i32, diff --git a/src/edid.rs b/src/edid.rs index e27e3071..523f9709 100644 --- a/src/edid.rs +++ b/src/edid.rs @@ -1,10 +1,10 @@ -use std::fmt::{Debug, Formatter}; -use std::rc::Rc; -use bstr::{BString, ByteSlice}; -use thiserror::Error; use crate::utils::bitflags::BitflagsExt; use crate::utils::ptr_ext::PtrExt; use crate::utils::stack::Stack; +use bstr::{BString, ByteSlice}; +use std::fmt::{Debug, Formatter}; +use std::rc::Rc; +use thiserror::Error; #[derive(Copy, Clone, Debug)] pub enum ColorBitDepth { @@ -26,7 +26,7 @@ pub enum DigitalVideoInterfaceStandard { HdmiB, MDDI, DisplayPort, - Unknown(u8) + Unknown(u8), } #[derive(Copy, Clone)] @@ -155,10 +155,18 @@ impl Debug for StereoViewingSupport { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { let msg = match *self { StereoViewingSupport::None => "none", - StereoViewingSupport::FieldSequentialRightDuringStereoSync => "field sequential, right during stereo sync", - StereoViewingSupport::FieldSequentialLeftDuringStereoSync => "field sequential, left during stereo sync", - StereoViewingSupport::TwoWayInterleavedRightImageOnEvenLines => "2-way interleaved, right image on even lines", - StereoViewingSupport::TwoWayInterleavedLeftImageOnEvenLines => "2-way interleaved, left image on even lines", + StereoViewingSupport::FieldSequentialRightDuringStereoSync => { + "field sequential, right during stereo sync" + } + StereoViewingSupport::FieldSequentialLeftDuringStereoSync => { + "field sequential, left during stereo sync" + } + StereoViewingSupport::TwoWayInterleavedRightImageOnEvenLines => { + "2-way interleaved, right image on even lines" + } + StereoViewingSupport::TwoWayInterleavedLeftImageOnEvenLines => { + "2-way interleaved, left image on even lines" + } StereoViewingSupport::FourWayInterleaved => "4-way interleaved", StereoViewingSupport::SideBySideInterleaved => "side-by-side interleaved", }; @@ -362,7 +370,7 @@ macro_rules! bail { ($slf:expr, $err:expr) => {{ $slf.saved_ctx = $slf.context.to_vec(); return Err($err); - }} + }}; } #[derive(Clone, Debug)] @@ -414,9 +422,7 @@ impl<'a> EdidParser<'a> { if self.data.len() - self.pos < N { bail!(self, EdidError::UnexpectedEof); } - let v = unsafe { - self.data[self.pos..].as_ptr().cast::<[u8; N]>().deref() - }; + let v = unsafe { self.data[self.pos..].as_ptr().cast::<[u8; N]>().deref() }; self.pos += N; Ok(v) } @@ -616,7 +622,11 @@ impl<'a> EdidParser<'a> { }) } - fn parse_standard_timings2(&mut self, revision: u8, b: &[u8; 18]) -> [Option; 6] { + fn parse_standard_timings2( + &mut self, + revision: u8, + b: &[u8; 18], + ) -> [Option; 6] { let mut res = [None; 6]; for i in 0..6 { let x = b[5 + 2 * i]; @@ -629,7 +639,7 @@ impl<'a> EdidParser<'a> { fn parse_color_point(&mut self, b: &[u8; 18]) -> (ColorPoint, Option) { let mut res = [Default::default(); 2]; for n in 0..2 { - let b = &b[5*(n + 1)..]; + let b = &b[5 * (n + 1)..]; res[n] = ColorPoint { white_point_index: b[0], white_point_x: ((b[2] as u16) << 2) | ((b[1] as u16) >> 2), @@ -649,7 +659,10 @@ impl<'a> EdidParser<'a> { (res[0], second) } - fn parse_standard_timings(&mut self, revision: u8) -> Result<[Option; 8], EdidError> { + fn parse_standard_timings( + &mut self, + revision: u8, + ) -> Result<[Option; 8], EdidError> { let _ctx = self.push_ctx(EdidParseContext::StandardTimings); let bytes = self.read_n::<16>()?; let mut res = [None; 8]; @@ -715,7 +728,10 @@ impl<'a> EdidParser<'a> { } } - fn parse_display_range_limits_and_additional_timing(&self, b: &[u8; 18]) -> DisplayRangeLimitsAndAdditionalTiming { + fn parse_display_range_limits_and_additional_timing( + &self, + b: &[u8; 18], + ) -> DisplayRangeLimitsAndAdditionalTiming { let min_vert_off = b[4].contains(0b0001); let max_vert_off = min_vert_off || b[4].contains(0b0010); let min_horz_off = b[4].contains(0b0100); @@ -767,56 +783,56 @@ impl<'a> EdidParser<'a> { preferred_vertical_refresh_rate_hz: b[17], }, n => ExtendedTimingInformation::Unknown(n), - } + }, } } fn parse_established_timings3(&self, b: &[u8; 18]) -> EstablishedTimings3 { EstablishedTimings3 { - s640x350_85: b[6].contains(0x80), - s640x400_85: b[6].contains(0x40), - s720x400_85: b[6].contains(0x20), - s640x480_85: b[6].contains(0x10), - s848x480_60: b[6].contains(0x08), - s800x600_85: b[6].contains(0x04), - s1024x768_85: b[6].contains(0x02), - s1152x864_75: b[6].contains(0x01), - s1280x768_60_rb: b[7].contains(0x80), - s1280x768_60: b[7].contains(0x40), - s1280x768_75: b[7].contains(0x20), - s1280x768_85: b[7].contains(0x10), - s1280x960_60: b[7].contains(0x08), - s1280x960_85: b[7].contains(0x04), - s1280x1024_60: b[7].contains(0x02), - s1280x1024_85: b[7].contains(0x01), - s1360x768_60: b[8].contains(0x80), - s1440x900_60_rb: b[8].contains(0x40), - s1440x900_60: b[8].contains(0x20), - s1440x900_75: b[8].contains(0x10), - s1440x900_85: b[8].contains(0x08), + s640x350_85: b[6].contains(0x80), + s640x400_85: b[6].contains(0x40), + s720x400_85: b[6].contains(0x20), + s640x480_85: b[6].contains(0x10), + s848x480_60: b[6].contains(0x08), + s800x600_85: b[6].contains(0x04), + s1024x768_85: b[6].contains(0x02), + s1152x864_75: b[6].contains(0x01), + s1280x768_60_rb: b[7].contains(0x80), + s1280x768_60: b[7].contains(0x40), + s1280x768_75: b[7].contains(0x20), + s1280x768_85: b[7].contains(0x10), + s1280x960_60: b[7].contains(0x08), + s1280x960_85: b[7].contains(0x04), + s1280x1024_60: b[7].contains(0x02), + s1280x1024_85: b[7].contains(0x01), + s1360x768_60: b[8].contains(0x80), + s1440x900_60_rb: b[8].contains(0x40), + s1440x900_60: b[8].contains(0x20), + s1440x900_75: b[8].contains(0x10), + s1440x900_85: b[8].contains(0x08), s1400x1050_60_rb: b[8].contains(0x04), - s1400x1050_60: b[8].contains(0x02), - s1400x1050_75: b[8].contains(0x01), - s1400x1050_85: b[9].contains(0x80), + s1400x1050_60: b[8].contains(0x02), + s1400x1050_75: b[8].contains(0x01), + s1400x1050_85: b[9].contains(0x80), s1680x1050_60_rb: b[9].contains(0x40), - s1680x1050_60: b[9].contains(0x20), - s1680x1050_75: b[9].contains(0x10), - s1680x1050_85: b[9].contains(0x08), - s1600x1200_60: b[9].contains(0x04), - s1600x1200_65: b[9].contains(0x02), - s1600x1200_70: b[9].contains(0x01), - s1600x1200_75: b[10].contains(0x80), - s1600x1200_85: b[10].contains(0x40), - s1792x1344_60: b[10].contains(0x20), - s1792x1344_75: b[10].contains(0x10), - s1856x1392_60: b[10].contains(0x08), - s1856x1392_75: b[10].contains(0x04), + s1680x1050_60: b[9].contains(0x20), + s1680x1050_75: b[9].contains(0x10), + s1680x1050_85: b[9].contains(0x08), + s1600x1200_60: b[9].contains(0x04), + s1600x1200_65: b[9].contains(0x02), + s1600x1200_70: b[9].contains(0x01), + s1600x1200_75: b[10].contains(0x80), + s1600x1200_85: b[10].contains(0x40), + s1792x1344_60: b[10].contains(0x20), + s1792x1344_75: b[10].contains(0x10), + s1856x1392_60: b[10].contains(0x08), + s1856x1392_75: b[10].contains(0x04), s1920x1200_60_rb: b[10].contains(0x02), - s1920x1200_60: b[10].contains(0x01), - s1920x1200_75: b[11].contains(0x80), - s1920x1200_85: b[11].contains(0x40), - s1920x1440_60: b[11].contains(0x20), - s1920x1440_75: b[11].contains(0x10), + s1920x1200_60: b[10].contains(0x01), + s1920x1200_75: b[11].contains(0x80), + s1920x1200_85: b[11].contains(0x40), + s1920x1440_60: b[11].contains(0x20), + s1920x1440_75: b[11].contains(0x10), } } @@ -872,13 +888,17 @@ impl<'a> EdidParser<'a> { match b[3] { 0xff => Descriptor::DisplayProductSerialNumber(str()), 0xfe => Descriptor::AlphanumericDataString(str()), - 0xfd => Descriptor::DisplayRangeLimitsAndAdditionalTiming(self.parse_display_range_limits_and_additional_timing(b)), + 0xfd => Descriptor::DisplayRangeLimitsAndAdditionalTiming( + self.parse_display_range_limits_and_additional_timing(b), + ), 0xfc => Descriptor::DisplayProductName(str()), 0xfb => { let (first, second) = self.parse_color_point(b); Descriptor::ColorPoint(first, second) - }, - 0xfa => Descriptor::StandardTimingIdentifier(self.parse_standard_timings2(revision, b)), + } + 0xfa => { + Descriptor::StandardTimingIdentifier(self.parse_standard_timings2(revision, b)) + } 0xf9 => Descriptor::ColorManagementData(self.parse_color_management_data(b)), 0xf8 => Descriptor::Cvt3ByteCode(self.parse_cvt3_byte_codes(b)), 0xf7 => Descriptor::EstablishedTimings3(self.parse_established_timings3(b)), @@ -923,7 +943,7 @@ impl<'a> EdidParser<'a> { } let &[edid_version, edid_revision] = self.read_n()?; let video_input_definition = self.parse_video_input_definition()?; - let is_digital = matches!(video_input_definition, VideoInputDefinition::Digital {..}); + let is_digital = matches!(video_input_definition, VideoInputDefinition::Digital { .. }); let screen_dimensions = self.parse_screen_dimensions()?; let gamma = self.parse_gamma()?; let feature_support = self.parse_feature_support(is_digital)?; @@ -1053,7 +1073,7 @@ pub fn parse(data: &[u8]) -> Result { pos: 0, context: Rc::new(Default::default()), saved_ctx: vec![], - errors: vec![] + errors: vec![], }; parser.parse() } diff --git a/src/ifs/wl_output.rs b/src/ifs/wl_output.rs index 3114f821..b365af1f 100644 --- a/src/ifs/wl_output.rs +++ b/src/ifs/wl_output.rs @@ -1,3 +1,4 @@ +use crate::backend; use crate::backend::Connector; use crate::client::{Client, ClientError, ClientId}; use crate::globals::{Global, GlobalName}; @@ -17,7 +18,6 @@ use std::cell::{Cell, RefCell}; use std::collections::hash_map::Entry; use std::rc::Rc; use thiserror::Error; -use crate::backend; const SP_UNKNOWN: i32 = 0; #[allow(dead_code)] diff --git a/src/ifs/wl_surface/xwindow.rs b/src/ifs/wl_surface/xwindow.rs index 73e5d968..2660104c 100644 --- a/src/ifs/wl_surface/xwindow.rs +++ b/src/ifs/wl_surface/xwindow.rs @@ -443,8 +443,7 @@ impl ToplevelNode for Xwindow { } fn accepts_keyboard_focus(&self) -> bool { - self.data.info.never_focus.get().not() && - self.data.info.icccm_hints.input.get() + self.data.info.never_focus.get().not() && self.data.info.icccm_hints.input.get() } fn default_surface(&self) -> Rc { diff --git a/src/main.rs b/src/main.rs index 1425346a..97d1e775 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,6 +47,7 @@ mod config; mod cursor; mod dbus; mod drm; +mod edid; mod event_loop; mod fixed; mod forker; @@ -78,7 +79,6 @@ mod wire_xcon; mod xcon; mod xkbcommon; mod xwayland; -mod edid; fn main() { cli::main(); diff --git a/src/render.rs b/src/render.rs index 12391656..31fd49e7 100644 --- a/src/render.rs +++ b/src/render.rs @@ -21,6 +21,7 @@ macro_rules! egl_transparent { use crate::drm::drm::DrmError; pub use renderer::*; use thiserror::Error; +use crate::drm::gbm::GbmError; mod egl; mod ext; @@ -49,6 +50,10 @@ pub enum RenderError { BindFailed, #[error("EGL library does not support device enumeration")] DeviceEnumeration, + #[error("EGL library does not support the GBM platform")] + GbmExt, + #[error("Could not create a GBM device")] + Gbm(#[source] GbmError), #[error("EGL library does not support device querying")] DeviceQuery, #[error("`eglQueryDeviceStringEXT` failed")] diff --git a/src/render/egl.rs b/src/render/egl.rs index 1fdcce80..12f10043 100644 --- a/src/render/egl.rs +++ b/src/render/egl.rs @@ -42,6 +42,9 @@ pub fn init() -> Result<(), RenderError> { if !EXTS.device_enumeration() { return Err(RenderError::DeviceEnumeration); } + if !EXTS.platform_gbm() { + return Err(RenderError::DeviceEnumeration); + } if EXTS.contains(ClientExt::KHR_DEBUG) { let attrib: &[EGLAttrib] = &[ EGL_DEBUG_MSG_CRITICAL_KHR as _, diff --git a/src/render/egl/device.rs b/src/render/egl/device.rs index 9c0560a0..51d92077 100644 --- a/src/render/egl/device.rs +++ b/src/render/egl/device.rs @@ -41,7 +41,8 @@ impl EglDevice { let mut dpy = EglDisplay { exts: DisplayExt::empty(), formats: Rc::new(AHashMap::new()), - dev: *self, + dev: Some(*self), + gbm: None, dpy, }; let mut major = 0; diff --git a/src/render/egl/display.rs b/src/render/egl/display.rs index a2faecfc..df4c6d2a 100644 --- a/src/render/egl/display.rs +++ b/src/render/egl/display.rs @@ -1,6 +1,7 @@ +use std::ptr; use crate::drm::dma::DmaBuf; use crate::drm::INVALID_MODIFIER; -use crate::format::Format; +use crate::format::{Format, formats}; use crate::render::egl::context::EglContext; use crate::render::egl::device::EglDevice; use crate::render::egl::image::EglImage; @@ -18,20 +19,75 @@ use crate::render::egl::sys::{ EGL_LINUX_DRM_FOURCC_EXT, EGL_NONE, EGL_TRUE, EGL_WIDTH, }; use crate::render::egl::PROCS; -use crate::render::ext::{get_gl_ext, DisplayExt, GlExt}; +use crate::render::ext::{get_gl_ext, DisplayExt, GlExt, get_display_ext}; use crate::render::RenderError; use ahash::AHashMap; use std::rc::Rc; +use crate::drm::drm::Drm; +use crate::drm::gbm::GbmDevice; +use crate::render::sys::{EGL_PLATFORM_GBM_KHR, eglInitialize}; -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct EglDisplay { pub exts: DisplayExt, pub formats: Rc>, - pub dev: EglDevice, + pub dev: Option, + pub gbm: Option, pub dpy: EGLDisplay, } impl EglDisplay { + pub fn create(drm: &Drm) -> Result, RenderError> { + unsafe { + let gbm = match GbmDevice::new(drm) { + Ok(gbm) => gbm, + Err(e) => return Err(RenderError::Gbm(e)), + }; + let dpy = PROCS.eglGetPlatformDisplayEXT( + EGL_PLATFORM_GBM_KHR as _, + gbm.raw() as _, + ptr::null(), + ); + if dpy.is_none() { + return Err(RenderError::GetDisplay); + } + let mut dpy = EglDisplay { + exts: DisplayExt::empty(), + formats: Rc::new(AHashMap::new()), + dev: None, + gbm: Some(gbm), + dpy, + }; + let mut major = 0; + let mut minor = 0; + if eglInitialize(dpy.dpy, &mut major, &mut minor) != EGL_TRUE { + return Err(RenderError::Initialize); + } + dpy.exts = get_display_ext(dpy.dpy); + if !dpy.exts.intersects(DisplayExt::KHR_IMAGE_BASE) { + return Err(RenderError::ImageBase); + } + if !dpy + .exts + .intersects(DisplayExt::EXT_IMAGE_DMA_BUF_IMPORT_MODIFIERS) + { + return Err(RenderError::DmaBufImport); + } + if !dpy + .exts + .intersects(DisplayExt::KHR_NO_CONFIG_CONTEXT | DisplayExt::MESA_CONFIGLESS_CONTEXT) + { + return Err(RenderError::ConfiglessContext); + } + if !dpy.exts.intersects(DisplayExt::KHR_SURFACELESS_CONTEXT) { + return Err(RenderError::SurfacelessContext); + } + dpy.formats = Rc::new(query_formats(dpy.dpy)?); + + Ok(Rc::new(dpy)) + } + } + pub fn create_context(self: &Rc) -> Result, RenderError> { let attrib = [EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE]; unsafe { @@ -141,3 +197,26 @@ impl Drop for EglDisplay { } } } + +unsafe fn query_formats(dpy: EGLDisplay) -> Result, RenderError> { + let mut vec = vec![]; + let mut num = 0; + let res = PROCS.eglQueryDmaBufFormatsEXT(dpy, num, ptr::null_mut(), &mut num); + if res != EGL_TRUE { + return Err(RenderError::QueryDmaBufFormats); + } + vec.reserve_exact(num as usize); + let res = PROCS.eglQueryDmaBufFormatsEXT(dpy, num, vec.as_mut_ptr(), &mut num); + if res != EGL_TRUE { + return Err(RenderError::QueryDmaBufFormats); + } + vec.set_len(num as usize); + let mut res = AHashMap::new(); + let formats = formats(); + for fmt in vec { + if let Some(format) = formats.get(&(fmt as u32)) { + res.insert(format.drm, *format); + } + } + Ok(res) +} diff --git a/src/render/egl/sys.rs b/src/render/egl/sys.rs index 262b164d..3a02ee09 100644 --- a/src/render/egl/sys.rs +++ b/src/render/egl/sys.rs @@ -52,6 +52,7 @@ pub const EGL_BAD_DEVICE_EXT: EGLint = 0x322B; pub const EGL_OPENGL_ES_API: EGLenum = 0x30A0; pub const EGL_DRM_DEVICE_FILE_EXT: EGLint = 0x3233; pub const EGL_PLATFORM_DEVICE_EXT: EGLint = 0x313F; +pub const EGL_PLATFORM_GBM_KHR: EGLint = 0x31D7; pub const EGL_CONTEXT_CLIENT_VERSION: EGLint = 0x3098; pub const EGL_WIDTH: EGLint = 0x3057; diff --git a/src/render/ext.rs b/src/render/ext.rs index 622a3d13..4da91a66 100644 --- a/src/render/ext.rs +++ b/src/render/ext.rs @@ -58,11 +58,15 @@ bitflags::bitflags! { impl ClientExt { pub fn device_enumeration(self) -> bool { - self.intersects(Self::EXT_DEVICE_BASE | Self::EXT_DEVICE_ENUMERATION) + self.contains(Self::EXT_DEVICE_BASE | Self::EXT_DEVICE_ENUMERATION) } pub fn device_query(self) -> bool { - self.intersects(Self::EXT_DEVICE_BASE | Self::EXT_DEVICE_QUERY) + self.contains(Self::EXT_DEVICE_BASE | Self::EXT_DEVICE_QUERY) + } + + pub fn platform_gbm(self) -> bool { + self.contains(Self::KHR_PLATFORM_GBM) } } diff --git a/src/render/renderer/context.rs b/src/render/renderer/context.rs index d6de4e5f..3dc01ad0 100644 --- a/src/render/renderer/context.rs +++ b/src/render/renderer/context.rs @@ -16,6 +16,7 @@ use std::ffi::CString; use std::fmt::{Debug, Formatter}; use std::rc::Rc; use uapi::ustr; +use crate::render::egl::display::EglDisplay; pub(super) struct TexProg { pub(super) prog: GlProgram, @@ -57,15 +58,14 @@ impl Debug for RenderContext { impl RenderContext { pub fn from_drm_device(drm: &Drm) -> Result { let nodes = drm.get_nodes()?; - let node = match nodes.get(&NodeType::Render) { + let node = match nodes + .get(&NodeType::Render) + .or_else(|| nodes.get(&NodeType::Primary)) + { None => return Err(RenderError::NoRenderNode), Some(path) => Rc::new(path.to_owned()), }; - let egl_dev = match find_drm_device(&nodes)? { - Some(d) => d, - None => return Err(RenderError::UnknownDrmDevice), - }; - let dpy = egl_dev.create_display()?; + let dpy = EglDisplay::create(drm)?; if !dpy.formats.contains_key(&XRGB8888.drm) { return Err(RenderError::XRGB888); } diff --git a/src/tasks/output.rs b/src/tasks/output.rs index 0c816512..46fa0f4f 100644 --- a/src/tasks/output.rs +++ b/src/tasks/output.rs @@ -5,7 +5,7 @@ use crate::state::State; use crate::tree::{OutputNode, OutputRenderData, WorkspaceNode}; use crate::utils::asyncevent::AsyncEvent; use crate::utils::clonecell::CloneCell; -use std::cell::{RefCell}; +use std::cell::RefCell; use std::rc::Rc; pub struct OutputHandler { @@ -21,7 +21,15 @@ impl OutputHandler { self.output.on_change(Rc::new(move || ae.trigger())); } let name = self.state.globals.name(); - let x1 = self.state.root.outputs.lock().values().map(|o| o.global.pos.get().x2()).max().unwrap_or(0); + let x1 = self + .state + .root + .outputs + .lock() + .values() + .map(|o| o.global.pos.get().x2()) + .max() + .unwrap_or(0); let global = Rc::new(WlOutputGlobal::new(name, self.output.clone(), x1)); let on = Rc::new(OutputNode { id: self.state.node_ids.next(), diff --git a/src/tree/output.rs b/src/tree/output.rs index 32aed8f4..41a8951c 100644 --- a/src/tree/output.rs +++ b/src/tree/output.rs @@ -1,3 +1,4 @@ +use crate::backend::Mode; use crate::cursor::KnownCursor; use crate::fixed::Fixed; use crate::ifs::wl_output::WlOutputGlobal; @@ -13,11 +14,10 @@ use crate::tree::{FindTreeResult, FoundNode, Node, NodeId, WorkspaceNode}; use crate::utils::clonecell::CloneCell; use crate::utils::errorfmt::ErrorFmt; use crate::utils::linkedlist::LinkedList; -use std::cell::{RefCell}; +use std::cell::RefCell; use std::fmt::{Debug, Formatter}; use std::ops::{Deref, Sub}; use std::rc::Rc; -use crate::backend::Mode; tree_id!(OutputNodeId); pub struct OutputNode { diff --git a/src/utils/stack.rs b/src/utils/stack.rs index 1867fa50..65b87597 100644 --- a/src/utils/stack.rs +++ b/src/utils/stack.rs @@ -25,7 +25,8 @@ impl Stack { } pub fn to_vec(&self) -> Vec - where T: Clone, + where + T: Clone, { unsafe { let v = self.vec.get().deref(); diff --git a/src/xcon/consts.rs b/src/xcon/consts.rs index 39fe11ec..1e7f130f 100644 --- a/src/xcon/consts.rs +++ b/src/xcon/consts.rs @@ -252,16 +252,16 @@ pub const _NET_WM_MOVERESIZE_SIZE_KEYBOARD: u32 = 9; pub const _NET_WM_MOVERESIZE_MOVE_KEYBOARD: u32 = 10; pub const _NET_WM_MOVERESIZE_CANCEL: u32 = 11; -pub const STACK_MODE_ABOVE : u32 = 0; -pub const STACK_MODE_BELOW : u32 = 1; -pub const STACK_MODE_TOP_IF : u32 = 2; -pub const STACK_MODE_BOTTOM_IF : u32 = 3; -pub const STACK_MODE_OPPOSITE : u32 = 4; +pub const STACK_MODE_ABOVE: u32 = 0; +pub const STACK_MODE_BELOW: u32 = 1; +pub const STACK_MODE_TOP_IF: u32 = 2; +pub const STACK_MODE_BOTTOM_IF: u32 = 3; +pub const STACK_MODE_OPPOSITE: u32 = 4; -pub const CONFIG_WINDOW_X : u16 = 1; -pub const CONFIG_WINDOW_Y : u16 = 2; -pub const CONFIG_WINDOW_WIDTH : u16 = 4; -pub const CONFIG_WINDOW_HEIGHT : u16 = 8; -pub const CONFIG_WINDOW_BORDER_WIDTH : u16 = 16; -pub const CONFIG_WINDOW_SIBLING : u16 = 32; -pub const CONFIG_WINDOW_STACK_MODE : u16 = 64; +pub const CONFIG_WINDOW_X: u16 = 1; +pub const CONFIG_WINDOW_Y: u16 = 2; +pub const CONFIG_WINDOW_WIDTH: u16 = 4; +pub const CONFIG_WINDOW_HEIGHT: u16 = 8; +pub const CONFIG_WINDOW_BORDER_WIDTH: u16 = 16; +pub const CONFIG_WINDOW_SIBLING: u16 = 32; +pub const CONFIG_WINDOW_STACK_MODE: u16 = 64; diff --git a/src/xwayland/xwm.rs b/src/xwayland/xwm.rs index 82c0d1aa..bdc3793e 100644 --- a/src/xwayland/xwm.rs +++ b/src/xwayland/xwm.rs @@ -9,8 +9,24 @@ use crate::utils::errorfmt::ErrorFmt; use crate::utils::linkedlist::LinkedList; use crate::utils::queue::AsyncQueue; use crate::wire::WlSurfaceId; -use crate::wire_xcon::{ChangeProperty, ChangeWindowAttributes, ClientMessage, CompositeRedirectSubwindows, ConfigureNotify, ConfigureRequest, ConfigureWindow, ConfigureWindowValues, CreateNotify, CreateWindow, CreateWindowValues, DestroyNotify, FocusIn, GetAtomName, GetGeometry, InternAtom, KillClient, MapNotify, MapRequest, MapWindow, PropertyNotify, ResClientIdSpec, ResQueryClientIds, SetInputFocus, SetSelectionOwner, UnmapNotify}; -use crate::xcon::consts::{ATOM_ATOM, ATOM_STRING, ATOM_WINDOW, ATOM_WM_CLASS, ATOM_WM_NAME, ATOM_WM_SIZE_HINTS, ATOM_WM_TRANSIENT_FOR, COMPOSITE_REDIRECT_MANUAL, EVENT_MASK_FOCUS_CHANGE, EVENT_MASK_PROPERTY_CHANGE, EVENT_MASK_SUBSTRUCTURE_NOTIFY, EVENT_MASK_SUBSTRUCTURE_REDIRECT, ICCCM_WM_HINT_INPUT, ICCCM_WM_STATE_ICONIC, ICCCM_WM_STATE_NORMAL, ICCCM_WM_STATE_WITHDRAWN, INPUT_FOCUS_POINTER_ROOT, MWM_HINTS_DECORATIONS_FIELD, MWM_HINTS_FLAGS_FIELD, NOTIFY_DETAIL_POINTER, NOTIFY_MODE_GRAB, NOTIFY_MODE_UNGRAB, PROP_MODE_REPLACE, RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID, WINDOW_CLASS_INPUT_OUTPUT, _NET_WM_STATE_ADD, _NET_WM_STATE_REMOVE, _NET_WM_STATE_TOGGLE, STACK_MODE_ABOVE, STACK_MODE_BELOW, CONFIG_WINDOW_X, CONFIG_WINDOW_Y, CONFIG_WINDOW_WIDTH, CONFIG_WINDOW_HEIGHT}; +use crate::wire_xcon::{ + ChangeProperty, ChangeWindowAttributes, ClientMessage, CompositeRedirectSubwindows, + ConfigureNotify, ConfigureRequest, ConfigureWindow, ConfigureWindowValues, CreateNotify, + CreateWindow, CreateWindowValues, DestroyNotify, FocusIn, GetAtomName, GetGeometry, InternAtom, + KillClient, MapNotify, MapRequest, MapWindow, PropertyNotify, ResClientIdSpec, + ResQueryClientIds, SetInputFocus, SetSelectionOwner, UnmapNotify, +}; +use crate::xcon::consts::{ + ATOM_ATOM, ATOM_STRING, ATOM_WINDOW, ATOM_WM_CLASS, ATOM_WM_NAME, ATOM_WM_SIZE_HINTS, + ATOM_WM_TRANSIENT_FOR, COMPOSITE_REDIRECT_MANUAL, CONFIG_WINDOW_HEIGHT, CONFIG_WINDOW_WIDTH, + CONFIG_WINDOW_X, CONFIG_WINDOW_Y, EVENT_MASK_FOCUS_CHANGE, EVENT_MASK_PROPERTY_CHANGE, + EVENT_MASK_SUBSTRUCTURE_NOTIFY, EVENT_MASK_SUBSTRUCTURE_REDIRECT, ICCCM_WM_HINT_INPUT, + ICCCM_WM_STATE_ICONIC, ICCCM_WM_STATE_NORMAL, ICCCM_WM_STATE_WITHDRAWN, + INPUT_FOCUS_POINTER_ROOT, MWM_HINTS_DECORATIONS_FIELD, MWM_HINTS_FLAGS_FIELD, + NOTIFY_DETAIL_POINTER, NOTIFY_MODE_GRAB, NOTIFY_MODE_UNGRAB, PROP_MODE_REPLACE, + RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID, STACK_MODE_ABOVE, STACK_MODE_BELOW, + WINDOW_CLASS_INPUT_OUTPUT, _NET_WM_STATE_ADD, _NET_WM_STATE_REMOVE, _NET_WM_STATE_TOGGLE, +}; use crate::xcon::{Event, XEvent, Xcon, XconError}; use crate::xwayland::{XWaylandError, XWaylandEvent}; use ahash::{AHashMap, AHashSet}; @@ -1014,9 +1030,7 @@ impl Wm { async fn handle_property_notify(&mut self, event: &Event) -> Result<(), XWaylandError> { let event: PropertyNotify = event.parse()?; - let name = self.c.call(&GetAtomName { - atom: event.atom, - }).await; + let name = self.c.call(&GetAtomName { atom: event.atom }).await; if let Ok(name) = name { log::info!("{}", name.get().name); } @@ -1258,17 +1272,20 @@ impl Wm { } }; *window.stack_link.borrow_mut() = Some(link); - let res = self.c.call(&ConfigureWindow { - window: window.window_id, - values: ConfigureWindowValues { - sibling: sibling.map(|s| s.window_id), - stack_mode: Some(match above { - true => STACK_MODE_ABOVE, - false => STACK_MODE_BELOW, - }), - ..Default::default() - }, - }).await; + let res = self + .c + .call(&ConfigureWindow { + window: window.window_id, + values: ConfigureWindowValues { + sibling: sibling.map(|s| s.window_id), + stack_mode: Some(match above { + true => STACK_MODE_ABOVE, + false => STACK_MODE_BELOW, + }), + ..Default::default() + }, + }) + .await; if let Err(e) = res { log::warn!("Could not restack window: {}", ErrorFmt(e)); } @@ -1339,7 +1356,9 @@ impl Wm { if event.value_mask.contains(CONFIG_WINDOW_HEIGHT) { height = event.height as _; } - data.info.extents.set(Rect::new_sized(x1, y1, width, height).unwrap()); + data.info + .extents + .set(Rect::new_sized(x1, y1, width, height).unwrap()); Ok(()) }