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)) => { Ok((output, should_expose)) => {
if 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()); wl_outputs.push(output.clone());
} }
device.outputs.insert(conn, output); device.outputs.insert(conn, output);
@ -335,7 +335,7 @@ impl State {
) { ) {
Ok((output, should_expose)) => { Ok((output, should_expose)) => {
if 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()); outputs_added.push(output.clone());
} }
@ -645,10 +645,10 @@ fn populate_modes(
output.add_mode(mode); output.add_mode(mode);
} }
output.set_preferred(output_mode); output.set_preferred(output_mode);
let transform = drm_helpers::panel_orientation(drm, conn).unwrap_or(Transform::Normal);
output.change_current_state( output.change_current_state(
Some(output_mode), Some(output_mode),
// TODO: Readout property for monitor rotation Some(transform),
Some(Transform::Normal),
Some(Scale::Fractional(scale)), Some(Scale::Fractional(scale)),
Some(Point::from((position.0 as i32, position.1 as i32))), Some(Point::from((position.0 as i32, position.1 as i32))),
); );
@ -663,6 +663,7 @@ fn populate_modes(
position, position,
max_bpc, max_bpc,
scale, scale,
transform,
..std::mem::take(&mut *output_config) ..std::mem::take(&mut *output_config)
}; };

View file

@ -1,13 +1,16 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use smithay::reexports::drm::control::{ use smithay::{
atomic::AtomicModeReq, reexports::drm::control::{
connector::{self, State as ConnectorState}, atomic::AtomicModeReq,
crtc, connector::{self, State as ConnectorState},
dumbbuffer::DumbBuffer, crtc,
property, AtomicCommitFlags, Device as ControlDevice, Mode, ModeFlags, PlaneType, dumbbuffer::DumbBuffer,
ResourceHandle, property, AtomicCommitFlags, Device as ControlDevice, Mode, ModeFlags, PlaneType,
ResourceHandle,
},
utils::Transform,
}; };
use std::{ use std::{
collections::HashMap, collections::HashMap,
@ -419,3 +422,21 @@ pub fn set_max_bpc(dev: &impl ControlDevice, conn: connector::Handle, bpc: u32)
_ => unreachable!(), _ => 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(), startup_done.clone(),
)?; )?;
if output.mirroring().is_none() { 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); all_outputs.push(output);
} }

View file

@ -139,6 +139,10 @@ impl OutputConfig {
self.mode.1.unwrap_or(60_000) 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 { pub fn output_mode(&self) -> Mode {
Mode { Mode {
size: self.mode_size(), size: self.mode_size(),

View file

@ -46,7 +46,6 @@ use smithay::{
utils::{IsAlive, Logical, Point, Rectangle, Serial, Size}, utils::{IsAlive, Logical, Point, Rectangle, Serial, Size},
wayland::{ wayland::{
compositor::{with_states, SurfaceAttributes}, compositor::{with_states, SurfaceAttributes},
foreign_toplevel_list::ForeignToplevelListState,
seat::WaylandFocus, seat::WaylandFocus,
session_lock::LockSurface, session_lock::LockSurface,
shell::wlr_layer::{KeyboardInteractivity, Layer, LayerSurfaceCachedState}, shell::wlr_layer::{KeyboardInteractivity, Layer, LayerSurfaceCachedState},

View file

@ -51,7 +51,7 @@ use smithay::{
PopupManager, PopupManager,
}, },
input::{pointer::CursorImageStatus, SeatState}, input::{pointer::CursorImageStatus, SeatState},
output::{Mode as OutputMode, Output, Scale}, output::{Output, Scale},
reexports::{ reexports::{
calloop::{LoopHandle, LoopSignal}, calloop::{LoopHandle, LoopSignal},
wayland_protocols::xdg::shell::server::xdg_toplevel::WmCapabilities, wayland_protocols::xdg::shell::server::xdg_toplevel::WmCapabilities,
@ -306,11 +306,7 @@ impl BackendData {
.unwrap() .unwrap()
.borrow(); .borrow();
let mode = Some(OutputMode { let mode = Some(final_config.output_mode()).filter(|m| match output.current_mode() {
size: final_config.mode_size(),
refresh: final_config.mode_refresh() as i32,
})
.filter(|m| match output.current_mode() {
None => true, None => true,
Some(c_m) => m.size != c_m.size || m.refresh != c_m.refresh, Some(c_m) => m.size != c_m.size || m.refresh != c_m.refresh,
}); });