mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-08 19:33:07 +00:00
gpu_display: sync with downstream code.
Notable changes: 1. Use "W" methods during window creation and message dispatching to ensure unicode characters are sent to the window. 2. In DisplayEventDispatcher::dispatch(), filter() and map() will be ignored if we don't call collect(). We replace map() with a for loop to make this clearer. Other changes are due to linter/formatter warnings, etc. Bug=b:213150276 TEST=cargo b -p gpu_display --features win64 --no-default-features Change-Id: I767aec208d8afd7d7cb86039d08ba8ec8369da81 Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3913991 Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Commit-Queue: Pujun Lun <lunpujun@google.com>
This commit is contained in:
parent
51f9faf3a4
commit
26d9803ccb
5 changed files with 51 additions and 62 deletions
|
@ -209,12 +209,11 @@ impl DisplayT for DisplayWin {
|
|||
}
|
||||
}
|
||||
|
||||
let display_closed_event = self.display_closed_event.try_clone().map_err(|e| {
|
||||
error!("Failed to clone display_closed_event: {}", e);
|
||||
GpuDisplayError::Allocate
|
||||
})?;
|
||||
Ok(Box::new(SurfaceWin {
|
||||
display_closed_event,
|
||||
display_closed_event: self.display_closed_event.try_clone().map_err(|e| {
|
||||
error!("Failed to clone display_closed_event: {}", e);
|
||||
GpuDisplayError::Allocate
|
||||
})?,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
// found in the LICENSE file.
|
||||
|
||||
use std::convert::From;
|
||||
use std::ffi::CString;
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
use std::os::raw::c_int;
|
||||
|
@ -23,6 +22,7 @@ use euclid::Size2D;
|
|||
use vm_control::display::WindowVisibility;
|
||||
use win_util::syscall_bail;
|
||||
use win_util::win32_string;
|
||||
use win_util::win32_wide_string;
|
||||
use winapi::shared::minwindef::DWORD;
|
||||
use winapi::shared::minwindef::FALSE;
|
||||
use winapi::shared::minwindef::HINSTANCE;
|
||||
|
@ -123,10 +123,7 @@ impl Window {
|
|||
info!("Creating window");
|
||||
static CONTEXT_MESSAGE: &str = "When creating Window";
|
||||
|
||||
let class_name = win32_string(class_name);
|
||||
let title = win32_string(title);
|
||||
let hinstance = Self::get_current_module_handle();
|
||||
|
||||
// If we fail to load any UI element below, use NULL to let the system use the default UI
|
||||
// rather than crash.
|
||||
let hicon = Self::load_custom_icon(hinstance, icon_resource_id).unwrap_or(null_mut());
|
||||
|
@ -136,21 +133,16 @@ impl Window {
|
|||
Self::register_window_class(
|
||||
wnd_proc,
|
||||
hinstance,
|
||||
&class_name,
|
||||
class_name,
|
||||
hicon,
|
||||
hcursor,
|
||||
hbrush_background,
|
||||
)
|
||||
.context(CONTEXT_MESSAGE)?;
|
||||
|
||||
let hwnd = Self::create_sys_window(
|
||||
hinstance,
|
||||
&class_name,
|
||||
&title,
|
||||
dw_style,
|
||||
initial_window_size,
|
||||
)
|
||||
.context(CONTEXT_MESSAGE)?;
|
||||
let hwnd =
|
||||
Self::create_sys_window(hinstance, class_name, title, dw_style, initial_window_size)
|
||||
.context(CONTEXT_MESSAGE)?;
|
||||
|
||||
Ok(Self {
|
||||
hwnd,
|
||||
|
@ -339,7 +331,7 @@ impl Window {
|
|||
/// Calls `MonitorFromWindow()` internally.
|
||||
pub fn is_on_active_display(&self) -> bool {
|
||||
// Safe because `Window` object won't outlive the HWND.
|
||||
unsafe { MonitorFromWindow(self.hwnd, MONITOR_DEFAULTTONULL) != null_mut() }
|
||||
unsafe { !MonitorFromWindow(self.hwnd, MONITOR_DEFAULTTONULL).is_null() }
|
||||
}
|
||||
|
||||
/// Calls `SetWindowPos()` internally.
|
||||
|
@ -499,8 +491,10 @@ impl Window {
|
|||
|
||||
/// Calls `GetWindowPlacement()` and `SetWindowPlacement()` internally.
|
||||
pub fn set_restored_pos(&self, window_rect: &Rect) -> Result<()> {
|
||||
let mut window_placement: WINDOWPLACEMENT = Default::default();
|
||||
window_placement.length = mem::size_of::<WINDOWPLACEMENT>().try_into().unwrap();
|
||||
let mut window_placement = WINDOWPLACEMENT {
|
||||
length: mem::size_of::<WINDOWPLACEMENT>().try_into().unwrap(),
|
||||
..Default::default()
|
||||
};
|
||||
// Safe because `Window` object won't outlive the HWND, we know `window_placement` is valid,
|
||||
// and failures are handled below.
|
||||
unsafe {
|
||||
|
@ -596,13 +590,13 @@ impl Window {
|
|||
fn register_window_class(
|
||||
wnd_proc: WNDPROC,
|
||||
hinstance: HINSTANCE,
|
||||
class_name: &CString,
|
||||
class_name: &str,
|
||||
hicon: HICON,
|
||||
hcursor: HCURSOR,
|
||||
hbrush_background: HBRUSH,
|
||||
) -> Result<()> {
|
||||
let window_class = WNDCLASSEXA {
|
||||
cbSize: std::mem::size_of::<WNDCLASSEXA>() as u32,
|
||||
let window_class = WNDCLASSEXW {
|
||||
cbSize: std::mem::size_of::<WNDCLASSEXW>() as u32,
|
||||
style: CS_OWNDC | CS_HREDRAW | CS_VREDRAW,
|
||||
lpfnWndProc: wnd_proc,
|
||||
cbClsExtra: 0,
|
||||
|
@ -612,14 +606,14 @@ impl Window {
|
|||
hCursor: hcursor,
|
||||
hbrBackground: hbrush_background,
|
||||
lpszMenuName: null_mut(),
|
||||
lpszClassName: class_name.as_ptr(),
|
||||
lpszClassName: win32_wide_string(class_name).as_ptr(),
|
||||
hIconSm: hicon,
|
||||
};
|
||||
|
||||
// Safe because we know the lifetime of `window_class`, and we handle failures below.
|
||||
unsafe {
|
||||
if RegisterClassExA(&window_class) == 0 {
|
||||
syscall_bail!("Failed to call RegisterClassExA()");
|
||||
if RegisterClassExW(&window_class) == 0 {
|
||||
syscall_bail!("Failed to call RegisterClassExW()");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -627,17 +621,17 @@ impl Window {
|
|||
|
||||
fn create_sys_window(
|
||||
hinstance: HINSTANCE,
|
||||
class_name: &CString,
|
||||
title: &CString,
|
||||
class_name: &str,
|
||||
title: &str,
|
||||
dw_style: DWORD,
|
||||
initial_window_size: &Size2D<i32, HostWindowSpace>,
|
||||
) -> Result<HWND> {
|
||||
// Safe because we handle failures below.
|
||||
unsafe {
|
||||
let hwnd = CreateWindowExA(
|
||||
let hwnd = CreateWindowExW(
|
||||
0,
|
||||
class_name.as_ptr(),
|
||||
title.as_ptr(),
|
||||
win32_wide_string(class_name).as_ptr(),
|
||||
win32_wide_string(title).as_ptr(),
|
||||
dw_style,
|
||||
0,
|
||||
0,
|
||||
|
@ -648,8 +642,8 @@ impl Window {
|
|||
hinstance,
|
||||
null_mut(),
|
||||
);
|
||||
if hwnd == null_mut() {
|
||||
syscall_bail!("Failed to call CreateWindowExA()");
|
||||
if hwnd.is_null() {
|
||||
syscall_bail!("Failed to call CreateWindowExW()");
|
||||
}
|
||||
Ok(hwnd)
|
||||
}
|
||||
|
@ -692,8 +686,10 @@ impl MonitorInfo {
|
|||
/// # Safety
|
||||
/// Caller is responsible for ensuring that `hmonitor` is a valid handle.
|
||||
unsafe fn get_monitor_info(hmonitor: HMONITOR) -> Result<MONITORINFO> {
|
||||
let mut monitor_info: MONITORINFO = Default::default();
|
||||
monitor_info.cbSize = mem::size_of::<MONITORINFO>().try_into().unwrap();
|
||||
let mut monitor_info = MONITORINFO {
|
||||
cbSize: mem::size_of::<MONITORINFO>().try_into().unwrap(),
|
||||
..Default::default()
|
||||
};
|
||||
if GetMonitorInfoA(hmonitor, &mut monitor_info) == 0 {
|
||||
syscall_bail!("Failed to call GetMonitorInfoA()");
|
||||
}
|
||||
|
|
|
@ -47,16 +47,16 @@ impl DisplayEventDispatcher {
|
|||
}
|
||||
|
||||
pub fn dispatch(&self, events: &[virtio_input_event], device_type: EventDeviceKind) {
|
||||
let _ = self
|
||||
for event_device in self
|
||||
.event_devices
|
||||
.borrow_mut()
|
||||
.iter_mut()
|
||||
.filter(|(_, event_device)| event_device.kind() == device_type)
|
||||
.map(|(_, event_device)| {
|
||||
if let Err(e) = event_device.send_report(events.iter().cloned()) {
|
||||
error!("Failed to send events to event device: {}", e);
|
||||
}
|
||||
});
|
||||
.values_mut()
|
||||
.filter(|event_device| event_device.kind() == device_type)
|
||||
{
|
||||
if let Err(e) = event_device.send_report(events.iter().cloned()) {
|
||||
error!("Failed to send events to event device: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn import_event_device(&mut self, event_device_id: ObjectId, event_device: EventDevice) {
|
||||
|
@ -187,7 +187,7 @@ impl<T: HandleWindowMessage> WindowMessageDispatcher<T> {
|
|||
}
|
||||
None => debug!("No window to destroy on WndProc thread drop"),
|
||||
},
|
||||
// Safe because we are processing a message tageting this thread.
|
||||
// Safe because we are processing a message targeting this thread.
|
||||
_ => unsafe {
|
||||
DefWindowProcA(null_mut(), msg, w_param, l_param);
|
||||
},
|
||||
|
|
|
@ -82,9 +82,6 @@ pub trait HandleWindowMessage {
|
|||
/// Called when processing `WM_SETFOCUS`.
|
||||
fn on_set_focus(&mut self) {}
|
||||
|
||||
/// Called when processing `WM_KILLFOCUS`.
|
||||
fn on_kill_focus(&mut self) {}
|
||||
|
||||
/// Called when processing `WM_INPUT`.
|
||||
fn on_raw_input(&mut self, _window: &Window, _l_param: LPARAM) {}
|
||||
|
||||
|
@ -92,7 +89,7 @@ pub trait HandleWindowMessage {
|
|||
fn on_mouse_move(&mut self, _w_param: WPARAM, _l_param: LPARAM) {}
|
||||
|
||||
/// Called when processing `WM_LBUTTONDOWN` and `WM_LBUTTONUP`.
|
||||
fn on_mouse_button_left(&mut self, _is_down: bool, _l_param: LPARAM) {}
|
||||
fn on_mouse_button_left(&mut self, _window: &Window, _is_down: bool, _l_param: LPARAM) {}
|
||||
|
||||
/// Called when processing `WM_RBUTTONDOWN` and `WM_RBUTTONUP`.
|
||||
fn on_mouse_button_right(&mut self, _is_down: bool) {}
|
||||
|
@ -225,10 +222,6 @@ impl<T: HandleWindowMessage> WindowMessageProcessor<T> {
|
|||
handler.on_set_focus();
|
||||
0
|
||||
}
|
||||
WM_KILLFOCUS => {
|
||||
handler.on_kill_focus();
|
||||
0
|
||||
}
|
||||
WM_INPUT => {
|
||||
handler.on_raw_input(&self.window, l_param);
|
||||
self.window.default_process_message(packet)
|
||||
|
@ -238,7 +231,8 @@ impl<T: HandleWindowMessage> WindowMessageProcessor<T> {
|
|||
0
|
||||
}
|
||||
WM_LBUTTONDOWN | WM_LBUTTONUP => {
|
||||
handler.on_mouse_button_left(/* is_down= */ msg == WM_LBUTTONDOWN, l_param);
|
||||
let is_down = msg == WM_LBUTTONDOWN;
|
||||
handler.on_mouse_button_left(&self.window, is_down, l_param);
|
||||
0
|
||||
}
|
||||
WM_RBUTTONDOWN | WM_RBUTTONUP => {
|
||||
|
|
|
@ -175,7 +175,7 @@ impl<T: HandleWindowMessage> WindowProcedureThread<T> {
|
|||
loop {
|
||||
let mut message = mem::MaybeUninit::uninit();
|
||||
// Safe because we know the lifetime of `message`.
|
||||
match unsafe { GetMessageA(message.as_mut_ptr(), null_mut(), 0, 0) } {
|
||||
match unsafe { GetMessageW(message.as_mut_ptr(), null_mut(), 0, 0) } {
|
||||
0 => {
|
||||
info!("WndProc thread exiting message loop since WM_QUIT is received");
|
||||
message_loop_state
|
||||
|
@ -184,7 +184,7 @@ impl<T: HandleWindowMessage> WindowProcedureThread<T> {
|
|||
}
|
||||
-1 => {
|
||||
error!(
|
||||
"WndProc thread exiting message loop because GetMessageA() failed with \
|
||||
"WndProc thread exiting message loop because GetMessageW() failed with \
|
||||
error code {}",
|
||||
unsafe { GetLastError() }
|
||||
);
|
||||
|
@ -195,19 +195,19 @@ impl<T: HandleWindowMessage> WindowProcedureThread<T> {
|
|||
_ => (),
|
||||
}
|
||||
|
||||
// Safe because `GetMessageA()` will block until `message` is populated.
|
||||
// Safe because `GetMessageW()` will block until `message` is populated.
|
||||
let new_message = unsafe { message.assume_init() };
|
||||
if new_message.hwnd == null_mut() {
|
||||
if new_message.hwnd.is_null() {
|
||||
// Thread messages don't target a specific window and `DispatchMessageA()` won't
|
||||
// send them to `wnd_proc()` function, hence we need to handle it as a special case.
|
||||
dispatcher
|
||||
.as_mut()
|
||||
.process_thread_message(&new_message.into());
|
||||
} else {
|
||||
// Safe because `GetMessageA()` will block until `message` is populated.
|
||||
// Safe because `GetMessageW()` will block until `message` is populated.
|
||||
unsafe {
|
||||
TranslateMessage(&new_message);
|
||||
DispatchMessageA(&new_message);
|
||||
DispatchMessageW(&new_message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -266,8 +266,8 @@ impl<T: HandleWindowMessage> WindowProcedureThread<T> {
|
|||
/// processing `WM_NCDESTROY`, because the window handle will become invalid afterwards.
|
||||
unsafe fn create_window() -> Result<Window> {
|
||||
// Gfxstream window is a child window of CrosVM window. Without WS_CLIPCHILDREN, the parent
|
||||
// window may use the background brush to clear the gfxstream window client area when drawing
|
||||
// occurs. This caused the screen flickering issue during resizing.
|
||||
// window may use the background brush to clear the gfxstream window client area when
|
||||
// drawing occurs. This caused the screen flickering issue during resizing.
|
||||
// See b/197786842 for details.
|
||||
let dw_style = WS_POPUP | WS_CLIPCHILDREN;
|
||||
Window::new(
|
||||
|
|
Loading…
Reference in a new issue