ZIm/crates/gpui/src/platform/windows/util.rs
张小白 4cb45e63f4
windows: Update windows-rs crate and better error handling in DirectWrite (#12818)
- Update `windows-rs` from `0.56` to `0.57`
- Use the newly introduced `Owned` struct in `0.57` to handle the RAII
stuff of `HANDLE`
- Better error handling in `DirectWrite`

Release Notes:

- N/A
2024-06-14 10:12:20 -07:00

128 lines
3.5 KiB
Rust

use std::sync::OnceLock;
use ::util::ResultExt;
use windows::Win32::{Foundation::*, UI::WindowsAndMessaging::*};
use crate::*;
pub(crate) trait HiLoWord {
fn hiword(&self) -> u16;
fn loword(&self) -> u16;
fn signed_hiword(&self) -> i16;
fn signed_loword(&self) -> i16;
}
impl HiLoWord for WPARAM {
fn hiword(&self) -> u16 {
((self.0 >> 16) & 0xFFFF) as u16
}
fn loword(&self) -> u16 {
(self.0 & 0xFFFF) as u16
}
fn signed_hiword(&self) -> i16 {
((self.0 >> 16) & 0xFFFF) as i16
}
fn signed_loword(&self) -> i16 {
(self.0 & 0xFFFF) as i16
}
}
impl HiLoWord for LPARAM {
fn hiword(&self) -> u16 {
((self.0 >> 16) & 0xFFFF) as u16
}
fn loword(&self) -> u16 {
(self.0 & 0xFFFF) as u16
}
fn signed_hiword(&self) -> i16 {
((self.0 >> 16) & 0xFFFF) as i16
}
fn signed_loword(&self) -> i16 {
(self.0 & 0xFFFF) as i16
}
}
pub(crate) unsafe fn get_window_long(hwnd: HWND, nindex: WINDOW_LONG_PTR_INDEX) -> isize {
#[cfg(target_pointer_width = "64")]
unsafe {
GetWindowLongPtrW(hwnd, nindex)
}
#[cfg(target_pointer_width = "32")]
unsafe {
GetWindowLongW(hwnd, nindex) as isize
}
}
pub(crate) unsafe fn set_window_long(
hwnd: HWND,
nindex: WINDOW_LONG_PTR_INDEX,
dwnewlong: isize,
) -> isize {
#[cfg(target_pointer_width = "64")]
unsafe {
SetWindowLongPtrW(hwnd, nindex, dwnewlong)
}
#[cfg(target_pointer_width = "32")]
unsafe {
SetWindowLongW(hwnd, nindex, dwnewlong as i32) as isize
}
}
pub(crate) fn windows_credentials_target_name(url: &str) -> String {
format!("zed:url={}", url)
}
pub(crate) fn load_cursor(style: CursorStyle) -> HCURSOR {
static ARROW: OnceLock<HCURSOR> = OnceLock::new();
static IBEAM: OnceLock<HCURSOR> = OnceLock::new();
static CROSS: OnceLock<HCURSOR> = OnceLock::new();
static HAND: OnceLock<HCURSOR> = OnceLock::new();
static SIZEWE: OnceLock<HCURSOR> = OnceLock::new();
static SIZENS: OnceLock<HCURSOR> = OnceLock::new();
static NO: OnceLock<HCURSOR> = OnceLock::new();
let (lock, name) = match style {
CursorStyle::IBeam | CursorStyle::IBeamCursorForVerticalLayout => (&IBEAM, IDC_IBEAM),
CursorStyle::Crosshair => (&CROSS, IDC_CROSS),
CursorStyle::PointingHand | CursorStyle::DragLink => (&HAND, IDC_HAND),
CursorStyle::ResizeLeft
| CursorStyle::ResizeRight
| CursorStyle::ResizeLeftRight
| CursorStyle::ResizeColumn => (&SIZEWE, IDC_SIZEWE),
CursorStyle::ResizeUp
| CursorStyle::ResizeDown
| CursorStyle::ResizeUpDown
| CursorStyle::ResizeRow => (&SIZENS, IDC_SIZENS),
CursorStyle::OperationNotAllowed => (&NO, IDC_NO),
_ => (&ARROW, IDC_ARROW),
};
*lock.get_or_init(|| {
HCURSOR(
unsafe { LoadImageW(None, name, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED) }
.log_err()
.unwrap_or_default()
.0,
)
})
}
#[inline]
pub(crate) fn logical_size(physical_size: Size<DevicePixels>, scale_factor: f32) -> Size<Pixels> {
Size {
width: px(physical_size.width.0 as f32 / scale_factor),
height: px(physical_size.height.0 as f32 / scale_factor),
}
}
#[inline]
pub(crate) fn logical_point(x: f32, y: f32, scale_factor: f32) -> Point<Pixels> {
Point {
x: px(x / scale_factor),
y: px(y / scale_factor),
}
}