| // Copyright 2022 The ChromiumOS Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| use std::sync::Weak; | |
| use base::AsRawDescriptor; | |
| use base::RawDescriptor; | |
| use base::ReadNotifier; | |
| use base::SendTube; | |
| use base::WaitContext; | |
| use metrics::sys::windows::Metrics; | |
| use crate::gpu_display_win::DisplayProperties; | |
| use crate::gpu_display_win::DisplayWin; | |
| use crate::DisplayEventToken; | |
| use crate::DisplayT; | |
| use crate::EventDevice; | |
| use crate::GpuDisplay; | |
| use crate::GpuDisplayExt; | |
| use crate::GpuDisplayResult; | |
| use crate::WindowProcedureThread; | |
| pub(crate) trait WinDisplayT: DisplayT { | |
| /// Imports an event device into the display backend. | |
| fn import_event_device( | |
| &mut self, | |
| _event_device_id: u32, | |
| _event_device: EventDevice, | |
| ) -> GpuDisplayResult<()> { | |
| Ok(()) | |
| } | |
| /// Called when the given event device is readable; in other words, when the guest sends data | |
| /// to the host (e.g. to set the numlock LED on/off). | |
| fn handle_event_device(&mut self, _event_device_id: u32) {} | |
| } | |
| impl GpuDisplayExt for GpuDisplay { | |
| fn import_event_device(&mut self, event_device: EventDevice) -> GpuDisplayResult<u32> { | |
| let new_event_device_id = self.next_id; | |
| // Safety (even though it's technically "safe"): event_device is owned by self.inner, and | |
| // will live until self.inner is dropped. | |
| self.wait_ctx.add( | |
| event_device.get_read_notifier(), | |
| DisplayEventToken::EventDevice { | |
| event_device_id: new_event_device_id, | |
| }, | |
| )?; | |
| self.inner | |
| .import_event_device(new_event_device_id, event_device)?; | |
| self.next_id += 1; | |
| Ok(new_event_device_id) | |
| } | |
| fn handle_event_device(&mut self, event_device_id: u32) { | |
| self.inner.handle_event_device(event_device_id); | |
| } | |
| } | |
| pub trait WinGpuDisplayExt { | |
| fn open_winapi( | |
| wndproc_thread: WindowProcedureThread, | |
| win_metrics: Option<Weak<Metrics>>, | |
| display_properties: DisplayProperties, | |
| gpu_display_wait_descriptor_ctrl: SendTube, | |
| ) -> GpuDisplayResult<GpuDisplay>; | |
| } | |
| impl WinGpuDisplayExt for GpuDisplay { | |
| fn open_winapi( | |
| wndproc_thread: WindowProcedureThread, | |
| win_metrics: Option<Weak<Metrics>>, | |
| display_properties: DisplayProperties, | |
| gpu_display_wait_descriptor_ctrl: SendTube, | |
| ) -> GpuDisplayResult<GpuDisplay> { | |
| let display = DisplayWin::new( | |
| wndproc_thread, | |
| win_metrics, | |
| display_properties, | |
| gpu_display_wait_descriptor_ctrl, | |
| )?; | |
| let wait_ctx = WaitContext::new()?; | |
| wait_ctx.add(&display, DisplayEventToken::Display)?; | |
| Ok(GpuDisplay { | |
| inner: Box::new(display), | |
| next_id: 1, | |
| event_devices: Default::default(), | |
| surfaces: Default::default(), | |
| imports: Default::default(), | |
| wait_ctx, | |
| }) | |
| } | |
| } | |
| impl AsRawDescriptor for GpuDisplay { | |
| fn as_raw_descriptor(&self) -> RawDescriptor { | |
| self.inner.as_raw_descriptor() | |
| } | |
| } |