Set default output transform based on DRM panel orientation (#901)

This commit is contained in:
Ian Douglas Scott 2024-10-07 12:12:40 -04:00 committed by GitHub
parent a96394f7a6
commit 15a6425836
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 40 additions and 19 deletions

View file

@ -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)
};

View file

@ -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<Transform> {
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")),
}
}

View file

@ -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);
}

View file

@ -139,6 +139,10 @@ impl OutputConfig {
self.mode.1.unwrap_or(60_000)
}
pub fn transformed_size(&self) -> Size<i32, Physical> {
self.transform.transform_size(self.mode_size())
}
pub fn output_mode(&self) -> Mode {
Mode {
size: self.mode_size(),

View file

@ -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},

View file

@ -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,
});