From 15a6425836ce36b5a98a5d423b1fba4ed6415bb2 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Mon, 7 Oct 2024 12:12:40 -0400 Subject: [PATCH] Set default output transform based on DRM `panel orientation` (#901) --- src/backend/kms/device.rs | 9 +++++---- src/backend/kms/drm_helpers.rs | 35 +++++++++++++++++++++++++++------- src/backend/kms/mod.rs | 2 +- src/config/mod.rs | 4 ++++ src/shell/mod.rs | 1 - src/state.rs | 8 ++------ 6 files changed, 40 insertions(+), 19 deletions(-) diff --git a/src/backend/kms/device.rs b/src/backend/kms/device.rs index a0949bc8..5fdd6446 100644 --- a/src/backend/kms/device.rs +++ b/src/backend/kms/device.rs @@ -237,7 +237,7 @@ impl State { ) { Ok((output, should_expose)) => { if should_expose { - w += output.config().mode_size().w as u32; + w += output.config().transformed_size().w as u32; wl_outputs.push(output.clone()); } device.outputs.insert(conn, output); @@ -335,7 +335,7 @@ impl State { ) { Ok((output, should_expose)) => { if should_expose { - w += output.config().mode_size().w as u32; + w += output.config().transformed_size().w as u32; outputs_added.push(output.clone()); } @@ -645,10 +645,10 @@ fn populate_modes( output.add_mode(mode); } output.set_preferred(output_mode); + let transform = drm_helpers::panel_orientation(drm, conn).unwrap_or(Transform::Normal); output.change_current_state( Some(output_mode), - // TODO: Readout property for monitor rotation - Some(Transform::Normal), + Some(transform), Some(Scale::Fractional(scale)), Some(Point::from((position.0 as i32, position.1 as i32))), ); @@ -663,6 +663,7 @@ fn populate_modes( position, max_bpc, scale, + transform, ..std::mem::take(&mut *output_config) }; diff --git a/src/backend/kms/drm_helpers.rs b/src/backend/kms/drm_helpers.rs index 909c6a27..2724a8bd 100644 --- a/src/backend/kms/drm_helpers.rs +++ b/src/backend/kms/drm_helpers.rs @@ -1,13 +1,16 @@ // SPDX-License-Identifier: GPL-3.0-only use anyhow::{anyhow, Result}; -use smithay::reexports::drm::control::{ - atomic::AtomicModeReq, - connector::{self, State as ConnectorState}, - crtc, - dumbbuffer::DumbBuffer, - property, AtomicCommitFlags, Device as ControlDevice, Mode, ModeFlags, PlaneType, - ResourceHandle, +use smithay::{ + reexports::drm::control::{ + atomic::AtomicModeReq, + connector::{self, State as ConnectorState}, + crtc, + dumbbuffer::DumbBuffer, + property, AtomicCommitFlags, Device as ControlDevice, Mode, ModeFlags, PlaneType, + ResourceHandle, + }, + utils::Transform, }; use std::{ collections::HashMap, @@ -419,3 +422,21 @@ pub fn set_max_bpc(dev: &impl ControlDevice, conn: connector::Handle, bpc: u32) _ => unreachable!(), }) } + +pub fn panel_orientation(dev: &impl ControlDevice, conn: connector::Handle) -> Result { + let (val_type, val) = get_property_val(dev, conn, "panel orientation")?; + match val_type.convert_value(val) { + property::Value::Enum(Some(val)) => match val.value() { + // "Normal" + 0 => Ok(Transform::Normal), + // "Upside Down" + 1 => Ok(Transform::_180), + // "Left Side Up" + 2 => Ok(Transform::_90), + // "Right Side Up" + 3 => Ok(Transform::_270), + _ => Err(anyhow!("panel orientation has invalid value '{:?}'", val)), + }, + _ => Err(anyhow!("panel orientation has wrong value type")), + } +} diff --git a/src/backend/kms/mod.rs b/src/backend/kms/mod.rs index 7073b88b..f1e19c28 100644 --- a/src/backend/kms/mod.rs +++ b/src/backend/kms/mod.rs @@ -686,7 +686,7 @@ impl KmsState { startup_done.clone(), )?; if output.mirroring().is_none() { - w += output.config().mode_size().w as u32; + w += output.config().transformed_size().w as u32; } all_outputs.push(output); } diff --git a/src/config/mod.rs b/src/config/mod.rs index 4baef38c..77db2951 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -139,6 +139,10 @@ impl OutputConfig { self.mode.1.unwrap_or(60_000) } + pub fn transformed_size(&self) -> Size { + self.transform.transform_size(self.mode_size()) + } + pub fn output_mode(&self) -> Mode { Mode { size: self.mode_size(), diff --git a/src/shell/mod.rs b/src/shell/mod.rs index c32f5cc5..5d44a43c 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -46,7 +46,6 @@ use smithay::{ utils::{IsAlive, Logical, Point, Rectangle, Serial, Size}, wayland::{ compositor::{with_states, SurfaceAttributes}, - foreign_toplevel_list::ForeignToplevelListState, seat::WaylandFocus, session_lock::LockSurface, shell::wlr_layer::{KeyboardInteractivity, Layer, LayerSurfaceCachedState}, diff --git a/src/state.rs b/src/state.rs index 5144cd9f..7a513a32 100644 --- a/src/state.rs +++ b/src/state.rs @@ -51,7 +51,7 @@ use smithay::{ PopupManager, }, input::{pointer::CursorImageStatus, SeatState}, - output::{Mode as OutputMode, Output, Scale}, + output::{Output, Scale}, reexports::{ calloop::{LoopHandle, LoopSignal}, wayland_protocols::xdg::shell::server::xdg_toplevel::WmCapabilities, @@ -306,11 +306,7 @@ impl BackendData { .unwrap() .borrow(); - let mode = Some(OutputMode { - size: final_config.mode_size(), - refresh: final_config.mode_refresh() as i32, - }) - .filter(|m| match output.current_mode() { + let mode = Some(final_config.output_mode()).filter(|m| match output.current_mode() { None => true, Some(c_m) => m.size != c_m.size || m.refresh != c_m.refresh, });