output: Take transform into account

Without handling transform, the surface was created with the wrong size on rotated displays, causing flicker before the .configure event arrived. With, it will attempt to set the right size from the start.
This commit is contained in:
Dorota Czaplejewicz
2019-10-19 20:45:27 +00:00
parent bd3b27eceb
commit afe8fd64f4

View File

@ -59,6 +59,36 @@ pub mod c {
}
}
/// Map to `wl_output.transform` values
#[derive(Clone)]
pub enum Transform {
Normal = 0,
Rotated90 = 1,
Rotated180 = 2,
Rotated270 = 3,
Flipped = 4,
FlippedRotated90 = 5,
FlippedRotated180 = 6,
FlippedRotated270 = 7,
}
impl Transform {
fn from_u32(v: u32) -> Option<Transform> {
use self::Transform::*;
match v {
0 => Some(Normal),
1 => Some(Rotated90),
2 => Some(Rotated180),
3 => Some(Rotated270),
4 => Some(Flipped),
5 => Some(FlippedRotated90),
6 => Some(FlippedRotated180),
7 => Some(FlippedRotated270),
_ => None,
}
}
}
extern "C" {
// Rustc wrongly assumes
// that COutputs allows C direct access to the underlying RefCell
@ -75,16 +105,32 @@ pub mod c {
// Defined in Rust
extern fn outputs_handle_geometry(
_outputs: COutputs,
_wl_output: WlOutput,
outputs: COutputs,
wl_output: WlOutput,
_x: i32, _y: i32,
_phys_width: i32, _phys_height: i32,
_subpixel: i32,
_make: *const c_char, _model: *const c_char,
_transform: i32,
transform: i32,
) {
//println!("geometry handled {},{}", x, y);
// Totally unused
let transform = Transform::from_u32(transform as u32).unwrap_or_else(
|| {
eprintln!(
"Warning: received invalid wl_output.transform value"
);
Transform::Normal
}
);
let outputs = outputs.clone_ref();
let mut collection = outputs.borrow_mut();
let output_state: Option<&mut OutputState>
= find_output_mut(&mut collection, wl_output)
.map(|o| &mut o.pending);
match output_state {
Some(state) => { state.transform = Some(transform) },
None => eprintln!("Wayland error: Got mode on unknown output"),
};
}
extern fn outputs_handle_mode(
@ -100,14 +146,12 @@ pub mod c {
Mode::NONE
});
let outputs = outputs.clone_ref();
let mut outputs = outputs.borrow_mut();
let mut output_state: Option<&mut OutputState> = outputs.outputs
.iter_mut()
.find_map(|o|
if o.output == wl_output { Some(&mut o.pending) } else { None }
);
let mut collection = outputs.borrow_mut();
let output_state: Option<&mut OutputState>
= find_output_mut(&mut collection, wl_output)
.map(|o| &mut o.pending);
match output_state {
Some(ref mut state) => {
Some(state) => {
if flags.contains(Mode::CURRENT) {
state.current_mode = Some(super::Mode { width, height});
}
@ -121,12 +165,10 @@ pub mod c {
wl_output: WlOutput,
) {
let outputs = outputs.clone_ref();
let mut outputs = outputs.borrow_mut();
let mut output = outputs.outputs
.iter_mut()
.find(|o| o.output == wl_output);
let mut collection = outputs.borrow_mut();
let output = find_output_mut(&mut collection, wl_output);
match output {
Some(ref mut output) => { output.current = output.pending.clone(); }
Some(output) => { output.current = output.pending.clone(); }
None => eprintln!("Wayland error: Got done on unknown output"),
};
}
@ -137,12 +179,10 @@ pub mod c {
factor: i32,
) {
let outputs = outputs.clone_ref();
let mut outputs = outputs.borrow_mut();
let output_state = outputs.outputs
.iter_mut()
.find_map(|o|
if o.output == wl_output { Some(&mut o.pending) } else { None }
);
let mut collection = outputs.borrow_mut();
let output_state: Option<&mut OutputState>
= find_output_mut(&mut collection, wl_output)
.map(|o| &mut o.pending);
match output_state {
Some(state) => { state.scale = factor; }
None => eprintln!("Wayland error: Got done on unknown output"),
@ -201,24 +241,51 @@ pub mod c {
let collection = raw_collection.clone_ref();
let collection = collection.borrow();
let output_state = collection.outputs
.iter()
.find_map(|o|
if o.output == wl_output { Some(&o.current) } else { None }
);
let output_state = find_output(&collection, wl_output)
.map(|o| &o.current);
match output_state {
Some(OutputState {
current_mode: Some(super::Mode { width, height: _ } ),
current_mode: Some(super::Mode { width, height } ),
transform: Some(transform),
scale,
}) => width / scale,
}) => {
match transform {
Transform::Normal
| Transform::Rotated180
| Transform::Flipped
| Transform::FlippedRotated180 => width / scale,
_ => height / scale,
}
},
_ => {
eprintln!("No width registered on output");
eprintln!("Not enough info registered on output");
0
},
}
}
// TODO: handle unregistration
fn find_output(
collection: &Outputs,
wl_output: WlOutput,
) -> Option<&Output> {
collection.outputs
.iter()
.find_map(|o|
if o.output == wl_output { Some(o) } else { None }
)
}
fn find_output_mut(
collection: &mut Outputs,
wl_output: WlOutput,
) -> Option<&mut Output> {
collection.outputs
.iter_mut()
.find_map(|o|
if o.output == wl_output { Some(o) } else { None }
)
}
}
#[derive(Clone)]
@ -230,6 +297,7 @@ struct Mode {
#[derive(Clone)]
pub struct OutputState {
current_mode: Option<Mode>,
transform: Option<c::Transform>,
scale: i32,
}
@ -237,6 +305,7 @@ impl OutputState {
fn uninitialized() -> OutputState {
OutputState {
current_mode: None,
transform: None,
scale: 1,
}
}