1 // Copyright 2022 The ChromiumOS Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 use std::convert::TryFrom; 6 use std::result::Result as StdResult; 7 use std::slice::Iter; 8 use std::time::SystemTime; 9 use std::time::UNIX_EPOCH; 10 11 use anyhow::anyhow; 12 use anyhow::Error as AnyError; 13 use anyhow::Result as AnyResult; 14 use serde::Deserialize; 15 use serde::Serialize; 16 17 #[derive(PartialEq, Eq, Clone, Copy, Serialize, Deserialize, Debug)] 18 pub enum WindowVisibility { 19 Hidden, 20 Minimized, 21 Normal, 22 } 23 24 #[derive(PartialEq, Eq, Clone, Copy, Serialize, Deserialize, Debug)] 25 pub enum WindowMode { 26 Unknown, 27 Fullscreen, 28 Windowed, 29 } 30 31 #[derive(PartialEq, Eq, Clone, Copy, Serialize, Deserialize, Debug)] 32 pub enum MouseMode { 33 Unknown, 34 Touchscreen, 35 Relative, 36 } 37 38 impl WindowMode { clone_or_default(&self, default: Self) -> Self39 pub fn clone_or_default(&self, default: Self) -> Self { 40 match *self { 41 Self::Unknown => default, 42 _ => *self, 43 } 44 } 45 next_mode(&self) -> AnyResult<Self>46 pub fn next_mode(&self) -> AnyResult<Self> { 47 match *self { 48 Self::Unknown => Err(anyhow!("No next mode for {:?}", self)), 49 Self::Fullscreen => Ok(Self::Windowed), 50 Self::Windowed => Ok(Self::Fullscreen), 51 } 52 } 53 } 54 55 #[derive(PartialEq, Eq, Clone, Copy, Serialize, Deserialize, Debug)] 56 pub enum AspectRatio { 57 Unknown, 58 W16H9, 59 W16H10, 60 W3H2, 61 W9H16, 62 } 63 64 impl AspectRatio { known_ratios_iter() -> Iter<'static, Self>65 pub fn known_ratios_iter() -> Iter<'static, Self> { 66 static KNOWN_RATIOS: [AspectRatio; 4] = [ 67 AspectRatio::W16H9, 68 AspectRatio::W16H10, 69 AspectRatio::W3H2, 70 AspectRatio::W9H16, 71 ]; 72 KNOWN_RATIOS.iter() 73 } 74 } 75 76 impl TryFrom<AspectRatio> for f32 { 77 type Error = AnyError; try_from(value: AspectRatio) -> StdResult<Self, Self::Error>78 fn try_from(value: AspectRatio) -> StdResult<Self, Self::Error> { 79 match value { 80 AspectRatio::Unknown => Err(anyhow!("Cannot convert {:?} to f32", value)), 81 AspectRatio::W16H9 => Ok(16.0 / 9.0), 82 AspectRatio::W16H10 => Ok(16.0 / 10.0), 83 AspectRatio::W3H2 => Ok(3.0 / 2.0), 84 AspectRatio::W9H16 => Ok(9.0 / 16.0), 85 } 86 } 87 } 88 89 impl TryFrom<f32> for AspectRatio { 90 type Error = AnyError; try_from(value: f32) -> StdResult<Self, Self::Error>91 fn try_from(value: f32) -> StdResult<Self, Self::Error> { 92 // To account for rounding errors, we allow the actual aspect ratio to differ from 93 // expectation by at most 0.01. 94 const EPSILON: f32 = 1e-2; 95 for aspect_ratio in Self::known_ratios_iter() { 96 if (value - f32::try_from(*aspect_ratio).unwrap()).abs() < EPSILON { 97 return Ok(*aspect_ratio); 98 } 99 } 100 Err(anyhow!( 101 "Cannot convert {:.3} to any aspect ratio enum", 102 value 103 )) 104 } 105 } 106 107 #[derive(PartialEq, Eq, Clone, Copy, Serialize, Deserialize, Debug)] 108 pub struct DisplaySize { 109 pub width: i32, 110 pub height: i32, 111 } 112 113 impl DisplaySize { new(width: i32, height: i32) -> Self114 pub fn new(width: i32, height: i32) -> Self { 115 Self { width, height } 116 } 117 shorter_edge(&self) -> i32118 pub fn shorter_edge(&self) -> i32 { 119 std::cmp::min(self.width, self.height) 120 } 121 } 122 123 #[derive(PartialEq, Eq, Clone, Copy, Serialize, Deserialize, Debug)] 124 pub struct GuestDisplayDensity { 125 pub static_landscape_dpi: i32, 126 pub static_portrait_dpi: i32, 127 pub dynamic_dpi: Option<i32>, 128 } 129 130 #[derive(PartialEq, Eq, Clone, Copy, Serialize, Deserialize, Debug)] 131 pub enum WindowEventCode { 132 Unspecified, 133 DisplaySettingsChange, 134 } 135 136 #[derive(PartialEq, Eq, Clone, Copy, Serialize, Deserialize, Debug)] 137 pub struct WindowEvent { 138 pub event_code: WindowEventCode, 139 pub report_timestamp_ms: i64, 140 } 141 142 impl WindowEvent { new(event_code: WindowEventCode) -> Self143 pub fn new(event_code: WindowEventCode) -> Self { 144 Self { 145 event_code, 146 report_timestamp_ms: SystemTime::now() 147 .duration_since(UNIX_EPOCH) 148 .unwrap() 149 .as_millis() as i64, 150 } 151 } 152 } 153