diff --git a/src/outputs.rs b/src/outputs.rs index 38326013..9692e954 100644 --- a/src/outputs.rs +++ b/src/outputs.rs @@ -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 { + 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, + transform: Option, scale: i32, } @@ -237,6 +305,7 @@ impl OutputState { fn uninitialized() -> OutputState { OutputState { current_mode: None, + transform: None, scale: 1, } }