autocommit 2022-04-04 14:29:04 CEST
This commit is contained in:
parent
1f71290dab
commit
e897d271af
21 changed files with 278 additions and 127 deletions
|
|
@ -205,7 +205,7 @@ impl MetalBackend {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let master = Rc::new(DrmMaster::new(res.fd.clone()));
|
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,
|
Ok(d) => d,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Could not initialize drm device: {}", ErrorFmt(e));
|
log::error!("Could not initialize drm device: {}", ErrorFmt(e));
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ use crate::utils::clonecell::CloneCell;
|
||||||
use crate::utils::errorfmt::ErrorFmt;
|
use crate::utils::errorfmt::ErrorFmt;
|
||||||
use crate::utils::numcell::NumCell;
|
use crate::utils::numcell::NumCell;
|
||||||
use crate::utils::oserror::OsError;
|
use crate::utils::oserror::OsError;
|
||||||
|
use crate::utils::syncqueue::SyncQueue;
|
||||||
use ahash::{AHashMap, AHashSet};
|
use ahash::{AHashMap, AHashSet};
|
||||||
use bstr::{BString, ByteSlice};
|
use bstr::{BString, ByteSlice};
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
@ -24,7 +25,6 @@ use std::ffi::CString;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use uapi::c;
|
use uapi::c;
|
||||||
use crate::utils::syncqueue::SyncQueue;
|
|
||||||
|
|
||||||
pub struct PendingDrmDevice {
|
pub struct PendingDrmDevice {
|
||||||
pub id: DrmId,
|
pub id: DrmId,
|
||||||
|
|
@ -405,7 +405,7 @@ impl<T: Copy> MutableProperty<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MetalBackend {
|
impl MetalBackend {
|
||||||
pub fn creat_drm_device(
|
pub fn create_drm_device(
|
||||||
self: &Rc<Self>,
|
self: &Rc<Self>,
|
||||||
pending: PendingDrmDevice,
|
pending: PendingDrmDevice,
|
||||||
master: &Rc<DrmMaster>,
|
master: &Rc<DrmMaster>,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
use crate::async_engine::{Phase, SpawnedFuture};
|
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::drm::{Drm, DrmError};
|
||||||
use crate::drm::gbm::{GbmDevice, GbmError, GBM_BO_USE_RENDERING};
|
use crate::drm::gbm::{GbmDevice, GbmError, GBM_BO_USE_RENDERING};
|
||||||
use crate::drm::{ModifiedFormat, INVALID_MODIFIER};
|
use crate::drm::{ModifiedFormat, INVALID_MODIFIER};
|
||||||
|
|
@ -12,6 +15,7 @@ use crate::utils::copyhashmap::CopyHashMap;
|
||||||
use crate::utils::errorfmt::ErrorFmt;
|
use crate::utils::errorfmt::ErrorFmt;
|
||||||
use crate::utils::numcell::NumCell;
|
use crate::utils::numcell::NumCell;
|
||||||
use crate::utils::queue::AsyncQueue;
|
use crate::utils::queue::AsyncQueue;
|
||||||
|
use crate::utils::syncqueue::SyncQueue;
|
||||||
use crate::wire_xcon::{
|
use crate::wire_xcon::{
|
||||||
ChangeProperty, ChangeWindowAttributes, ConfigureNotify, CreateCursor, CreatePixmap,
|
ChangeProperty, ChangeWindowAttributes, ConfigureNotify, CreateCursor, CreatePixmap,
|
||||||
CreateWindow, CreateWindowValues, DestroyNotify, Dri3Open, Dri3PixmapFromBuffer,
|
CreateWindow, CreateWindowValues, DestroyNotify, Dri3Open, Dri3PixmapFromBuffer,
|
||||||
|
|
@ -39,7 +43,6 @@ use std::cell::{Cell, RefCell};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use crate::utils::syncqueue::SyncQueue;
|
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum XBackendError {
|
pub enum XBackendError {
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,11 @@ use crate::drm::INVALID_MODIFIER;
|
||||||
use crate::utils::errorfmt::ErrorFmt;
|
use crate::utils::errorfmt::ErrorFmt;
|
||||||
use crate::utils::stack::Stack;
|
use crate::utils::stack::Stack;
|
||||||
use crate::utils::syncqueue::SyncQueue;
|
use crate::utils::syncqueue::SyncQueue;
|
||||||
|
use crate::utils::vec_ext::VecExt;
|
||||||
pub use sys::{
|
pub use sys::{
|
||||||
drm_mode_modeinfo, DRM_CLIENT_CAP_ATOMIC, DRM_MODE_ATOMIC_ALLOW_MODESET,
|
drm_mode_modeinfo, DRM_CLIENT_CAP_ATOMIC, DRM_MODE_ATOMIC_ALLOW_MODESET,
|
||||||
DRM_MODE_ATOMIC_NONBLOCK, DRM_MODE_PAGE_FLIP_EVENT,
|
DRM_MODE_ATOMIC_NONBLOCK, DRM_MODE_PAGE_FLIP_EVENT,
|
||||||
};
|
};
|
||||||
use crate::utils::vec_ext::VecExt;
|
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum DrmError {
|
pub enum DrmError {
|
||||||
|
|
@ -108,11 +108,15 @@ fn reopen(fd: c::c_int, need_primary: bool) -> Result<Rc<OwnedFd>, DrmError> {
|
||||||
if let Ok((fd, _)) = create_lease(fd, &[], c::O_CLOEXEC as _) {
|
if let Ok((fd, _)) = create_lease(fd, &[], c::O_CLOEXEC as _) {
|
||||||
return Ok(Rc::new(fd));
|
return Ok(Rc::new(fd));
|
||||||
}
|
}
|
||||||
let path = if get_node_type_from_fd(fd).map_err(DrmError::GetDeviceType)? == NodeType::Render {
|
let path = 'path: {
|
||||||
uapi::format_ustr!("/proc/self/fd/{}", fd)
|
if get_node_type_from_fd(fd).map_err(DrmError::GetDeviceType)? == NodeType::Render {
|
||||||
} else if !need_primary {
|
break 'path uapi::format_ustr!("/proc/self/fd/{}", fd);
|
||||||
render_node_name(fd)?
|
}
|
||||||
} else {
|
if !need_primary {
|
||||||
|
if let Ok(path) = render_node_name(fd) {
|
||||||
|
break 'path path;
|
||||||
|
}
|
||||||
|
}
|
||||||
device_node_name(fd)?
|
device_node_name(fd)?
|
||||||
};
|
};
|
||||||
match uapi::open(&path, c::O_RDWR | c::O_CLOEXEC, 0) {
|
match uapi::open(&path, c::O_RDWR | c::O_CLOEXEC, 0) {
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ pub enum GbmError {
|
||||||
DrmFd,
|
DrmFd,
|
||||||
}
|
}
|
||||||
|
|
||||||
type Device = u8;
|
pub type Device = u8;
|
||||||
type Bo = u8;
|
type Bo = u8;
|
||||||
|
|
||||||
pub const GBM_BO_USE_SCANOUT: u32 = 1 << 0;
|
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(
|
pub fn create_bo(
|
||||||
&self,
|
&self,
|
||||||
width: i32,
|
width: i32,
|
||||||
|
|
|
||||||
148
src/edid.rs
148
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::bitflags::BitflagsExt;
|
||||||
use crate::utils::ptr_ext::PtrExt;
|
use crate::utils::ptr_ext::PtrExt;
|
||||||
use crate::utils::stack::Stack;
|
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)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum ColorBitDepth {
|
pub enum ColorBitDepth {
|
||||||
|
|
@ -26,7 +26,7 @@ pub enum DigitalVideoInterfaceStandard {
|
||||||
HdmiB,
|
HdmiB,
|
||||||
MDDI,
|
MDDI,
|
||||||
DisplayPort,
|
DisplayPort,
|
||||||
Unknown(u8)
|
Unknown(u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
|
@ -155,10 +155,18 @@ impl Debug for StereoViewingSupport {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
let msg = match *self {
|
let msg = match *self {
|
||||||
StereoViewingSupport::None => "none",
|
StereoViewingSupport::None => "none",
|
||||||
StereoViewingSupport::FieldSequentialRightDuringStereoSync => "field sequential, right during stereo sync",
|
StereoViewingSupport::FieldSequentialRightDuringStereoSync => {
|
||||||
StereoViewingSupport::FieldSequentialLeftDuringStereoSync => "field sequential, left during stereo sync",
|
"field sequential, right during stereo sync"
|
||||||
StereoViewingSupport::TwoWayInterleavedRightImageOnEvenLines => "2-way interleaved, right image on even lines",
|
}
|
||||||
StereoViewingSupport::TwoWayInterleavedLeftImageOnEvenLines => "2-way interleaved, left image on even lines",
|
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::FourWayInterleaved => "4-way interleaved",
|
||||||
StereoViewingSupport::SideBySideInterleaved => "side-by-side interleaved",
|
StereoViewingSupport::SideBySideInterleaved => "side-by-side interleaved",
|
||||||
};
|
};
|
||||||
|
|
@ -362,7 +370,7 @@ macro_rules! bail {
|
||||||
($slf:expr, $err:expr) => {{
|
($slf:expr, $err:expr) => {{
|
||||||
$slf.saved_ctx = $slf.context.to_vec();
|
$slf.saved_ctx = $slf.context.to_vec();
|
||||||
return Err($err);
|
return Err($err);
|
||||||
}}
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
@ -414,9 +422,7 @@ impl<'a> EdidParser<'a> {
|
||||||
if self.data.len() - self.pos < N {
|
if self.data.len() - self.pos < N {
|
||||||
bail!(self, EdidError::UnexpectedEof);
|
bail!(self, EdidError::UnexpectedEof);
|
||||||
}
|
}
|
||||||
let v = unsafe {
|
let v = unsafe { self.data[self.pos..].as_ptr().cast::<[u8; N]>().deref() };
|
||||||
self.data[self.pos..].as_ptr().cast::<[u8; N]>().deref()
|
|
||||||
};
|
|
||||||
self.pos += N;
|
self.pos += N;
|
||||||
Ok(v)
|
Ok(v)
|
||||||
}
|
}
|
||||||
|
|
@ -616,7 +622,11 @@ impl<'a> EdidParser<'a> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_standard_timings2(&mut self, revision: u8, b: &[u8; 18]) -> [Option<StandardTiming>; 6] {
|
fn parse_standard_timings2(
|
||||||
|
&mut self,
|
||||||
|
revision: u8,
|
||||||
|
b: &[u8; 18],
|
||||||
|
) -> [Option<StandardTiming>; 6] {
|
||||||
let mut res = [None; 6];
|
let mut res = [None; 6];
|
||||||
for i in 0..6 {
|
for i in 0..6 {
|
||||||
let x = b[5 + 2 * i];
|
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<ColorPoint>) {
|
fn parse_color_point(&mut self, b: &[u8; 18]) -> (ColorPoint, Option<ColorPoint>) {
|
||||||
let mut res = [Default::default(); 2];
|
let mut res = [Default::default(); 2];
|
||||||
for n in 0..2 {
|
for n in 0..2 {
|
||||||
let b = &b[5*(n + 1)..];
|
let b = &b[5 * (n + 1)..];
|
||||||
res[n] = ColorPoint {
|
res[n] = ColorPoint {
|
||||||
white_point_index: b[0],
|
white_point_index: b[0],
|
||||||
white_point_x: ((b[2] as u16) << 2) | ((b[1] as u16) >> 2),
|
white_point_x: ((b[2] as u16) << 2) | ((b[1] as u16) >> 2),
|
||||||
|
|
@ -649,7 +659,10 @@ impl<'a> EdidParser<'a> {
|
||||||
(res[0], second)
|
(res[0], second)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_standard_timings(&mut self, revision: u8) -> Result<[Option<StandardTiming>; 8], EdidError> {
|
fn parse_standard_timings(
|
||||||
|
&mut self,
|
||||||
|
revision: u8,
|
||||||
|
) -> Result<[Option<StandardTiming>; 8], EdidError> {
|
||||||
let _ctx = self.push_ctx(EdidParseContext::StandardTimings);
|
let _ctx = self.push_ctx(EdidParseContext::StandardTimings);
|
||||||
let bytes = self.read_n::<16>()?;
|
let bytes = self.read_n::<16>()?;
|
||||||
let mut res = [None; 8];
|
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 min_vert_off = b[4].contains(0b0001);
|
||||||
let max_vert_off = min_vert_off || b[4].contains(0b0010);
|
let max_vert_off = min_vert_off || b[4].contains(0b0010);
|
||||||
let min_horz_off = b[4].contains(0b0100);
|
let min_horz_off = b[4].contains(0b0100);
|
||||||
|
|
@ -767,56 +783,56 @@ impl<'a> EdidParser<'a> {
|
||||||
preferred_vertical_refresh_rate_hz: b[17],
|
preferred_vertical_refresh_rate_hz: b[17],
|
||||||
},
|
},
|
||||||
n => ExtendedTimingInformation::Unknown(n),
|
n => ExtendedTimingInformation::Unknown(n),
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_established_timings3(&self, b: &[u8; 18]) -> EstablishedTimings3 {
|
fn parse_established_timings3(&self, b: &[u8; 18]) -> EstablishedTimings3 {
|
||||||
EstablishedTimings3 {
|
EstablishedTimings3 {
|
||||||
s640x350_85: b[6].contains(0x80),
|
s640x350_85: b[6].contains(0x80),
|
||||||
s640x400_85: b[6].contains(0x40),
|
s640x400_85: b[6].contains(0x40),
|
||||||
s720x400_85: b[6].contains(0x20),
|
s720x400_85: b[6].contains(0x20),
|
||||||
s640x480_85: b[6].contains(0x10),
|
s640x480_85: b[6].contains(0x10),
|
||||||
s848x480_60: b[6].contains(0x08),
|
s848x480_60: b[6].contains(0x08),
|
||||||
s800x600_85: b[6].contains(0x04),
|
s800x600_85: b[6].contains(0x04),
|
||||||
s1024x768_85: b[6].contains(0x02),
|
s1024x768_85: b[6].contains(0x02),
|
||||||
s1152x864_75: b[6].contains(0x01),
|
s1152x864_75: b[6].contains(0x01),
|
||||||
s1280x768_60_rb: b[7].contains(0x80),
|
s1280x768_60_rb: b[7].contains(0x80),
|
||||||
s1280x768_60: b[7].contains(0x40),
|
s1280x768_60: b[7].contains(0x40),
|
||||||
s1280x768_75: b[7].contains(0x20),
|
s1280x768_75: b[7].contains(0x20),
|
||||||
s1280x768_85: b[7].contains(0x10),
|
s1280x768_85: b[7].contains(0x10),
|
||||||
s1280x960_60: b[7].contains(0x08),
|
s1280x960_60: b[7].contains(0x08),
|
||||||
s1280x960_85: b[7].contains(0x04),
|
s1280x960_85: b[7].contains(0x04),
|
||||||
s1280x1024_60: b[7].contains(0x02),
|
s1280x1024_60: b[7].contains(0x02),
|
||||||
s1280x1024_85: b[7].contains(0x01),
|
s1280x1024_85: b[7].contains(0x01),
|
||||||
s1360x768_60: b[8].contains(0x80),
|
s1360x768_60: b[8].contains(0x80),
|
||||||
s1440x900_60_rb: b[8].contains(0x40),
|
s1440x900_60_rb: b[8].contains(0x40),
|
||||||
s1440x900_60: b[8].contains(0x20),
|
s1440x900_60: b[8].contains(0x20),
|
||||||
s1440x900_75: b[8].contains(0x10),
|
s1440x900_75: b[8].contains(0x10),
|
||||||
s1440x900_85: b[8].contains(0x08),
|
s1440x900_85: b[8].contains(0x08),
|
||||||
s1400x1050_60_rb: b[8].contains(0x04),
|
s1400x1050_60_rb: b[8].contains(0x04),
|
||||||
s1400x1050_60: b[8].contains(0x02),
|
s1400x1050_60: b[8].contains(0x02),
|
||||||
s1400x1050_75: b[8].contains(0x01),
|
s1400x1050_75: b[8].contains(0x01),
|
||||||
s1400x1050_85: b[9].contains(0x80),
|
s1400x1050_85: b[9].contains(0x80),
|
||||||
s1680x1050_60_rb: b[9].contains(0x40),
|
s1680x1050_60_rb: b[9].contains(0x40),
|
||||||
s1680x1050_60: b[9].contains(0x20),
|
s1680x1050_60: b[9].contains(0x20),
|
||||||
s1680x1050_75: b[9].contains(0x10),
|
s1680x1050_75: b[9].contains(0x10),
|
||||||
s1680x1050_85: b[9].contains(0x08),
|
s1680x1050_85: b[9].contains(0x08),
|
||||||
s1600x1200_60: b[9].contains(0x04),
|
s1600x1200_60: b[9].contains(0x04),
|
||||||
s1600x1200_65: b[9].contains(0x02),
|
s1600x1200_65: b[9].contains(0x02),
|
||||||
s1600x1200_70: b[9].contains(0x01),
|
s1600x1200_70: b[9].contains(0x01),
|
||||||
s1600x1200_75: b[10].contains(0x80),
|
s1600x1200_75: b[10].contains(0x80),
|
||||||
s1600x1200_85: b[10].contains(0x40),
|
s1600x1200_85: b[10].contains(0x40),
|
||||||
s1792x1344_60: b[10].contains(0x20),
|
s1792x1344_60: b[10].contains(0x20),
|
||||||
s1792x1344_75: b[10].contains(0x10),
|
s1792x1344_75: b[10].contains(0x10),
|
||||||
s1856x1392_60: b[10].contains(0x08),
|
s1856x1392_60: b[10].contains(0x08),
|
||||||
s1856x1392_75: b[10].contains(0x04),
|
s1856x1392_75: b[10].contains(0x04),
|
||||||
s1920x1200_60_rb: b[10].contains(0x02),
|
s1920x1200_60_rb: b[10].contains(0x02),
|
||||||
s1920x1200_60: b[10].contains(0x01),
|
s1920x1200_60: b[10].contains(0x01),
|
||||||
s1920x1200_75: b[11].contains(0x80),
|
s1920x1200_75: b[11].contains(0x80),
|
||||||
s1920x1200_85: b[11].contains(0x40),
|
s1920x1200_85: b[11].contains(0x40),
|
||||||
s1920x1440_60: b[11].contains(0x20),
|
s1920x1440_60: b[11].contains(0x20),
|
||||||
s1920x1440_75: b[11].contains(0x10),
|
s1920x1440_75: b[11].contains(0x10),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -872,13 +888,17 @@ impl<'a> EdidParser<'a> {
|
||||||
match b[3] {
|
match b[3] {
|
||||||
0xff => Descriptor::DisplayProductSerialNumber(str()),
|
0xff => Descriptor::DisplayProductSerialNumber(str()),
|
||||||
0xfe => Descriptor::AlphanumericDataString(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()),
|
0xfc => Descriptor::DisplayProductName(str()),
|
||||||
0xfb => {
|
0xfb => {
|
||||||
let (first, second) = self.parse_color_point(b);
|
let (first, second) = self.parse_color_point(b);
|
||||||
Descriptor::ColorPoint(first, second)
|
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)),
|
0xf9 => Descriptor::ColorManagementData(self.parse_color_management_data(b)),
|
||||||
0xf8 => Descriptor::Cvt3ByteCode(self.parse_cvt3_byte_codes(b)),
|
0xf8 => Descriptor::Cvt3ByteCode(self.parse_cvt3_byte_codes(b)),
|
||||||
0xf7 => Descriptor::EstablishedTimings3(self.parse_established_timings3(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 &[edid_version, edid_revision] = self.read_n()?;
|
||||||
let video_input_definition = self.parse_video_input_definition()?;
|
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 screen_dimensions = self.parse_screen_dimensions()?;
|
||||||
let gamma = self.parse_gamma()?;
|
let gamma = self.parse_gamma()?;
|
||||||
let feature_support = self.parse_feature_support(is_digital)?;
|
let feature_support = self.parse_feature_support(is_digital)?;
|
||||||
|
|
@ -1053,7 +1073,7 @@ pub fn parse(data: &[u8]) -> Result<EdidFile, EdidError> {
|
||||||
pos: 0,
|
pos: 0,
|
||||||
context: Rc::new(Default::default()),
|
context: Rc::new(Default::default()),
|
||||||
saved_ctx: vec![],
|
saved_ctx: vec![],
|
||||||
errors: vec![]
|
errors: vec![],
|
||||||
};
|
};
|
||||||
parser.parse()
|
parser.parse()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::backend;
|
||||||
use crate::backend::Connector;
|
use crate::backend::Connector;
|
||||||
use crate::client::{Client, ClientError, ClientId};
|
use crate::client::{Client, ClientError, ClientId};
|
||||||
use crate::globals::{Global, GlobalName};
|
use crate::globals::{Global, GlobalName};
|
||||||
|
|
@ -17,7 +18,6 @@ use std::cell::{Cell, RefCell};
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use crate::backend;
|
|
||||||
|
|
||||||
const SP_UNKNOWN: i32 = 0;
|
const SP_UNKNOWN: i32 = 0;
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
|
|
||||||
|
|
@ -443,8 +443,7 @@ impl ToplevelNode for Xwindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accepts_keyboard_focus(&self) -> bool {
|
fn accepts_keyboard_focus(&self) -> bool {
|
||||||
self.data.info.never_focus.get().not() &&
|
self.data.info.never_focus.get().not() && self.data.info.icccm_hints.input.get()
|
||||||
self.data.info.icccm_hints.input.get()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_surface(&self) -> Rc<WlSurface> {
|
fn default_surface(&self) -> Rc<WlSurface> {
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ mod config;
|
||||||
mod cursor;
|
mod cursor;
|
||||||
mod dbus;
|
mod dbus;
|
||||||
mod drm;
|
mod drm;
|
||||||
|
mod edid;
|
||||||
mod event_loop;
|
mod event_loop;
|
||||||
mod fixed;
|
mod fixed;
|
||||||
mod forker;
|
mod forker;
|
||||||
|
|
@ -78,7 +79,6 @@ mod wire_xcon;
|
||||||
mod xcon;
|
mod xcon;
|
||||||
mod xkbcommon;
|
mod xkbcommon;
|
||||||
mod xwayland;
|
mod xwayland;
|
||||||
mod edid;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
cli::main();
|
cli::main();
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ macro_rules! egl_transparent {
|
||||||
use crate::drm::drm::DrmError;
|
use crate::drm::drm::DrmError;
|
||||||
pub use renderer::*;
|
pub use renderer::*;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
use crate::drm::gbm::GbmError;
|
||||||
|
|
||||||
mod egl;
|
mod egl;
|
||||||
mod ext;
|
mod ext;
|
||||||
|
|
@ -49,6 +50,10 @@ pub enum RenderError {
|
||||||
BindFailed,
|
BindFailed,
|
||||||
#[error("EGL library does not support device enumeration")]
|
#[error("EGL library does not support device enumeration")]
|
||||||
DeviceEnumeration,
|
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")]
|
#[error("EGL library does not support device querying")]
|
||||||
DeviceQuery,
|
DeviceQuery,
|
||||||
#[error("`eglQueryDeviceStringEXT` failed")]
|
#[error("`eglQueryDeviceStringEXT` failed")]
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,9 @@ pub fn init() -> Result<(), RenderError> {
|
||||||
if !EXTS.device_enumeration() {
|
if !EXTS.device_enumeration() {
|
||||||
return Err(RenderError::DeviceEnumeration);
|
return Err(RenderError::DeviceEnumeration);
|
||||||
}
|
}
|
||||||
|
if !EXTS.platform_gbm() {
|
||||||
|
return Err(RenderError::DeviceEnumeration);
|
||||||
|
}
|
||||||
if EXTS.contains(ClientExt::KHR_DEBUG) {
|
if EXTS.contains(ClientExt::KHR_DEBUG) {
|
||||||
let attrib: &[EGLAttrib] = &[
|
let attrib: &[EGLAttrib] = &[
|
||||||
EGL_DEBUG_MSG_CRITICAL_KHR as _,
|
EGL_DEBUG_MSG_CRITICAL_KHR as _,
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,8 @@ impl EglDevice {
|
||||||
let mut dpy = EglDisplay {
|
let mut dpy = EglDisplay {
|
||||||
exts: DisplayExt::empty(),
|
exts: DisplayExt::empty(),
|
||||||
formats: Rc::new(AHashMap::new()),
|
formats: Rc::new(AHashMap::new()),
|
||||||
dev: *self,
|
dev: Some(*self),
|
||||||
|
gbm: None,
|
||||||
dpy,
|
dpy,
|
||||||
};
|
};
|
||||||
let mut major = 0;
|
let mut major = 0;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
|
use std::ptr;
|
||||||
use crate::drm::dma::DmaBuf;
|
use crate::drm::dma::DmaBuf;
|
||||||
use crate::drm::INVALID_MODIFIER;
|
use crate::drm::INVALID_MODIFIER;
|
||||||
use crate::format::Format;
|
use crate::format::{Format, formats};
|
||||||
use crate::render::egl::context::EglContext;
|
use crate::render::egl::context::EglContext;
|
||||||
use crate::render::egl::device::EglDevice;
|
use crate::render::egl::device::EglDevice;
|
||||||
use crate::render::egl::image::EglImage;
|
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,
|
EGL_LINUX_DRM_FOURCC_EXT, EGL_NONE, EGL_TRUE, EGL_WIDTH,
|
||||||
};
|
};
|
||||||
use crate::render::egl::PROCS;
|
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 crate::render::RenderError;
|
||||||
use ahash::AHashMap;
|
use ahash::AHashMap;
|
||||||
use std::rc::Rc;
|
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 struct EglDisplay {
|
||||||
pub exts: DisplayExt,
|
pub exts: DisplayExt,
|
||||||
pub formats: Rc<AHashMap<u32, &'static Format>>,
|
pub formats: Rc<AHashMap<u32, &'static Format>>,
|
||||||
pub dev: EglDevice,
|
pub dev: Option<EglDevice>,
|
||||||
|
pub gbm: Option<GbmDevice>,
|
||||||
pub dpy: EGLDisplay,
|
pub dpy: EGLDisplay,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EglDisplay {
|
impl EglDisplay {
|
||||||
|
pub fn create(drm: &Drm) -> Result<Rc<Self>, 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<Self>) -> Result<Rc<EglContext>, RenderError> {
|
pub fn create_context(self: &Rc<Self>) -> Result<Rc<EglContext>, RenderError> {
|
||||||
let attrib = [EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE];
|
let attrib = [EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE];
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
@ -141,3 +197,26 @@ impl Drop for EglDisplay {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe fn query_formats(dpy: EGLDisplay) -> Result<AHashMap<u32, &'static Format>, 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)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ pub const EGL_BAD_DEVICE_EXT: EGLint = 0x322B;
|
||||||
pub const EGL_OPENGL_ES_API: EGLenum = 0x30A0;
|
pub const EGL_OPENGL_ES_API: EGLenum = 0x30A0;
|
||||||
pub const EGL_DRM_DEVICE_FILE_EXT: EGLint = 0x3233;
|
pub const EGL_DRM_DEVICE_FILE_EXT: EGLint = 0x3233;
|
||||||
pub const EGL_PLATFORM_DEVICE_EXT: EGLint = 0x313F;
|
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_CONTEXT_CLIENT_VERSION: EGLint = 0x3098;
|
||||||
|
|
||||||
pub const EGL_WIDTH: EGLint = 0x3057;
|
pub const EGL_WIDTH: EGLint = 0x3057;
|
||||||
|
|
|
||||||
|
|
@ -58,11 +58,15 @@ bitflags::bitflags! {
|
||||||
|
|
||||||
impl ClientExt {
|
impl ClientExt {
|
||||||
pub fn device_enumeration(self) -> bool {
|
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 {
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ use std::ffi::CString;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use uapi::ustr;
|
use uapi::ustr;
|
||||||
|
use crate::render::egl::display::EglDisplay;
|
||||||
|
|
||||||
pub(super) struct TexProg {
|
pub(super) struct TexProg {
|
||||||
pub(super) prog: GlProgram,
|
pub(super) prog: GlProgram,
|
||||||
|
|
@ -57,15 +58,14 @@ impl Debug for RenderContext {
|
||||||
impl RenderContext {
|
impl RenderContext {
|
||||||
pub fn from_drm_device(drm: &Drm) -> Result<Self, RenderError> {
|
pub fn from_drm_device(drm: &Drm) -> Result<Self, RenderError> {
|
||||||
let nodes = drm.get_nodes()?;
|
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),
|
None => return Err(RenderError::NoRenderNode),
|
||||||
Some(path) => Rc::new(path.to_owned()),
|
Some(path) => Rc::new(path.to_owned()),
|
||||||
};
|
};
|
||||||
let egl_dev = match find_drm_device(&nodes)? {
|
let dpy = EglDisplay::create(drm)?;
|
||||||
Some(d) => d,
|
|
||||||
None => return Err(RenderError::UnknownDrmDevice),
|
|
||||||
};
|
|
||||||
let dpy = egl_dev.create_display()?;
|
|
||||||
if !dpy.formats.contains_key(&XRGB8888.drm) {
|
if !dpy.formats.contains_key(&XRGB8888.drm) {
|
||||||
return Err(RenderError::XRGB888);
|
return Err(RenderError::XRGB888);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use crate::state::State;
|
||||||
use crate::tree::{OutputNode, OutputRenderData, WorkspaceNode};
|
use crate::tree::{OutputNode, OutputRenderData, WorkspaceNode};
|
||||||
use crate::utils::asyncevent::AsyncEvent;
|
use crate::utils::asyncevent::AsyncEvent;
|
||||||
use crate::utils::clonecell::CloneCell;
|
use crate::utils::clonecell::CloneCell;
|
||||||
use std::cell::{RefCell};
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub struct OutputHandler {
|
pub struct OutputHandler {
|
||||||
|
|
@ -21,7 +21,15 @@ impl OutputHandler {
|
||||||
self.output.on_change(Rc::new(move || ae.trigger()));
|
self.output.on_change(Rc::new(move || ae.trigger()));
|
||||||
}
|
}
|
||||||
let name = self.state.globals.name();
|
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 global = Rc::new(WlOutputGlobal::new(name, self.output.clone(), x1));
|
||||||
let on = Rc::new(OutputNode {
|
let on = Rc::new(OutputNode {
|
||||||
id: self.state.node_ids.next(),
|
id: self.state.node_ids.next(),
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::backend::Mode;
|
||||||
use crate::cursor::KnownCursor;
|
use crate::cursor::KnownCursor;
|
||||||
use crate::fixed::Fixed;
|
use crate::fixed::Fixed;
|
||||||
use crate::ifs::wl_output::WlOutputGlobal;
|
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::clonecell::CloneCell;
|
||||||
use crate::utils::errorfmt::ErrorFmt;
|
use crate::utils::errorfmt::ErrorFmt;
|
||||||
use crate::utils::linkedlist::LinkedList;
|
use crate::utils::linkedlist::LinkedList;
|
||||||
use std::cell::{RefCell};
|
use std::cell::RefCell;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
use std::ops::{Deref, Sub};
|
use std::ops::{Deref, Sub};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use crate::backend::Mode;
|
|
||||||
|
|
||||||
tree_id!(OutputNodeId);
|
tree_id!(OutputNodeId);
|
||||||
pub struct OutputNode {
|
pub struct OutputNode {
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,8 @@ impl<T> Stack<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_vec(&self) -> Vec<T>
|
pub fn to_vec(&self) -> Vec<T>
|
||||||
where T: Clone,
|
where
|
||||||
|
T: Clone,
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let v = self.vec.get().deref();
|
let v = self.vec.get().deref();
|
||||||
|
|
|
||||||
|
|
@ -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_MOVE_KEYBOARD: u32 = 10;
|
||||||
pub const _NET_WM_MOVERESIZE_CANCEL: u32 = 11;
|
pub const _NET_WM_MOVERESIZE_CANCEL: u32 = 11;
|
||||||
|
|
||||||
pub const STACK_MODE_ABOVE : u32 = 0;
|
pub const STACK_MODE_ABOVE: u32 = 0;
|
||||||
pub const STACK_MODE_BELOW : u32 = 1;
|
pub const STACK_MODE_BELOW: u32 = 1;
|
||||||
pub const STACK_MODE_TOP_IF : u32 = 2;
|
pub const STACK_MODE_TOP_IF: u32 = 2;
|
||||||
pub const STACK_MODE_BOTTOM_IF : u32 = 3;
|
pub const STACK_MODE_BOTTOM_IF: u32 = 3;
|
||||||
pub const STACK_MODE_OPPOSITE : u32 = 4;
|
pub const STACK_MODE_OPPOSITE: u32 = 4;
|
||||||
|
|
||||||
pub const CONFIG_WINDOW_X : u16 = 1;
|
pub const CONFIG_WINDOW_X: u16 = 1;
|
||||||
pub const CONFIG_WINDOW_Y : u16 = 2;
|
pub const CONFIG_WINDOW_Y: u16 = 2;
|
||||||
pub const CONFIG_WINDOW_WIDTH : u16 = 4;
|
pub const CONFIG_WINDOW_WIDTH: u16 = 4;
|
||||||
pub const CONFIG_WINDOW_HEIGHT : u16 = 8;
|
pub const CONFIG_WINDOW_HEIGHT: u16 = 8;
|
||||||
pub const CONFIG_WINDOW_BORDER_WIDTH : u16 = 16;
|
pub const CONFIG_WINDOW_BORDER_WIDTH: u16 = 16;
|
||||||
pub const CONFIG_WINDOW_SIBLING : u16 = 32;
|
pub const CONFIG_WINDOW_SIBLING: u16 = 32;
|
||||||
pub const CONFIG_WINDOW_STACK_MODE : u16 = 64;
|
pub const CONFIG_WINDOW_STACK_MODE: u16 = 64;
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,24 @@ use crate::utils::errorfmt::ErrorFmt;
|
||||||
use crate::utils::linkedlist::LinkedList;
|
use crate::utils::linkedlist::LinkedList;
|
||||||
use crate::utils::queue::AsyncQueue;
|
use crate::utils::queue::AsyncQueue;
|
||||||
use crate::wire::WlSurfaceId;
|
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::wire_xcon::{
|
||||||
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};
|
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::xcon::{Event, XEvent, Xcon, XconError};
|
||||||
use crate::xwayland::{XWaylandError, XWaylandEvent};
|
use crate::xwayland::{XWaylandError, XWaylandEvent};
|
||||||
use ahash::{AHashMap, AHashSet};
|
use ahash::{AHashMap, AHashSet};
|
||||||
|
|
@ -1014,9 +1030,7 @@ impl Wm {
|
||||||
|
|
||||||
async fn handle_property_notify(&mut self, event: &Event) -> Result<(), XWaylandError> {
|
async fn handle_property_notify(&mut self, event: &Event) -> Result<(), XWaylandError> {
|
||||||
let event: PropertyNotify = event.parse()?;
|
let event: PropertyNotify = event.parse()?;
|
||||||
let name = self.c.call(&GetAtomName {
|
let name = self.c.call(&GetAtomName { atom: event.atom }).await;
|
||||||
atom: event.atom,
|
|
||||||
}).await;
|
|
||||||
if let Ok(name) = name {
|
if let Ok(name) = name {
|
||||||
log::info!("{}", name.get().name);
|
log::info!("{}", name.get().name);
|
||||||
}
|
}
|
||||||
|
|
@ -1258,17 +1272,20 @@ impl Wm {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
*window.stack_link.borrow_mut() = Some(link);
|
*window.stack_link.borrow_mut() = Some(link);
|
||||||
let res = self.c.call(&ConfigureWindow {
|
let res = self
|
||||||
window: window.window_id,
|
.c
|
||||||
values: ConfigureWindowValues {
|
.call(&ConfigureWindow {
|
||||||
sibling: sibling.map(|s| s.window_id),
|
window: window.window_id,
|
||||||
stack_mode: Some(match above {
|
values: ConfigureWindowValues {
|
||||||
true => STACK_MODE_ABOVE,
|
sibling: sibling.map(|s| s.window_id),
|
||||||
false => STACK_MODE_BELOW,
|
stack_mode: Some(match above {
|
||||||
}),
|
true => STACK_MODE_ABOVE,
|
||||||
..Default::default()
|
false => STACK_MODE_BELOW,
|
||||||
},
|
}),
|
||||||
}).await;
|
..Default::default()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.await;
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
log::warn!("Could not restack window: {}", ErrorFmt(e));
|
log::warn!("Could not restack window: {}", ErrorFmt(e));
|
||||||
}
|
}
|
||||||
|
|
@ -1339,7 +1356,9 @@ impl Wm {
|
||||||
if event.value_mask.contains(CONFIG_WINDOW_HEIGHT) {
|
if event.value_mask.contains(CONFIG_WINDOW_HEIGHT) {
|
||||||
height = event.height as _;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue