#![allow(non_snake_case)]
use core::ffi::c_void;
pub type Handle = *mut c_void;
pub type Wparam = usize;
pub type Lparam = isize;
pub type Lresult = isize;
pub type Bool32 = i32;
pub type WindowProc = unsafe extern "system" fn(Handle, u32, Wparam, Lparam) -> Lresult;
pub type MonitorEnumProc = unsafe extern "system" fn(Handle, Handle, *mut Rect, Lparam) -> Bool32;
pub type EnumResNameProc =
unsafe extern "system" fn(Handle, *const u16, *mut u16, Lparam) -> Bool32;
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct Rect {
pub left: i32,
pub top: i32,
pub right: i32,
pub bottom: i32,
}
impl Rect {
pub const fn width(self) -> i32 {
if self.right > self.left {
self.right - self.left
} else {
0
}
}
pub const fn height(self) -> i32 {
if self.bottom > self.top {
self.bottom - self.top
} else {
0
}
}
#[cfg(test)]
pub const fn intersect(self, other: Self) -> Self {
let left = if self.left > other.left {
self.left
} else {
other.left
};
let top = if self.top > other.top {
self.top
} else {
other.top
};
let right = if self.right < other.right {
self.right
} else {
other.right
};
let bottom = if self.bottom < other.bottom {
self.bottom
} else {
other.bottom
};
Self {
left,
top,
right,
bottom,
}
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct AppBarData {
pub cb_size: u32,
pub hwnd: Handle,
pub callback_message: u32,
pub edge: u32,
pub rc: Rect,
pub l_param: Lparam,
}
impl AppBarData {
pub fn new(hwnd: Handle) -> Self {
Self {
cb_size: size_of::<Self>() as u32,
hwnd,
callback_message: 0,
edge: 0,
rc: Rect::default(),
l_param: 0,
}
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct Point {
pub x: i32,
pub y: i32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct Msg {
pub hwnd: Handle,
pub message: u32,
pub w_param: Wparam,
pub l_param: Lparam,
pub time: u32,
pub pt: Point,
pub l_private: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct WndClassExW {
pub cb_size: u32,
pub style: u32,
pub lpfn_wnd_proc: WindowProc,
pub cb_cls_extra: i32,
pub cb_wnd_extra: i32,
pub h_instance: Handle,
pub h_icon: Handle,
pub h_cursor: Handle,
pub hbr_background: Handle,
pub lpsz_menu_name: *const u16,
pub lpsz_class_name: *const u16,
pub h_icon_sm: Handle,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct CreateStructW {
pub lp_create_params: *mut c_void,
pub h_instance: Handle,
pub h_menu: Handle,
pub hwnd_parent: Handle,
pub cy: i32,
pub cx: i32,
pub y: i32,
pub x: i32,
pub style: i32,
pub lpsz_name: *const u16,
pub lpsz_class: *const u16,
pub dw_ex_style: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct MinMaxInfo {
pub pt_reserved: Point,
pub pt_max_size: Point,
pub pt_max_position: Point,
pub pt_min_track_size: Point,
pub pt_max_track_size: Point,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct WindowPlacement {
pub length: u32,
pub flags: u32,
pub show_cmd: u32,
pub pt_min_position: Point,
pub pt_max_position: Point,
pub rc_normal_position: Rect,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct MonitorInfoExW {
pub cb_size: u32,
pub rc_monitor: Rect,
pub rc_work: Rect,
pub dw_flags: u32,
pub sz_device: [u16; 32],
}
impl Default for MonitorInfoExW {
fn default() -> Self {
Self {
cb_size: size_of::<Self>() as u32,
rc_monitor: Rect::default(),
rc_work: Rect::default(),
dw_flags: 0,
sz_device: [0; 32],
}
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct DevModeW {
pub dm_device_name: [u16; 32],
pub dm_spec_version: u16,
pub dm_driver_version: u16,
pub dm_size: u16,
pub dm_driver_extra: u16,
pub dm_fields: u32,
pub dm_position: Point,
pub dm_display_orientation: u32,
pub dm_display_fixed_output: u32,
pub dm_color: i16,
pub dm_duplex: i16,
pub dm_y_resolution: i16,
pub dm_tt_option: i16,
pub dm_collate: i16,
pub dm_form_name: [u16; 32],
pub dm_log_pixels: u16,
pub dm_bits_per_pel: u32,
pub dm_pels_width: u32,
pub dm_pels_height: u32,
pub dm_display_flags: u32,
pub dm_display_frequency: u32,
pub dm_icm_method: u32,
pub dm_icm_intent: u32,
pub dm_media_type: u32,
pub dm_dither_type: u32,
pub dm_reserved1: u32,
pub dm_reserved2: u32,
pub dm_panning_width: u32,
pub dm_panning_height: u32,
}
impl Default for DevModeW {
fn default() -> Self {
Self {
dm_device_name: [0; 32],
dm_spec_version: 0,
dm_driver_version: 0,
dm_size: size_of::<Self>() as u16,
dm_driver_extra: 0,
dm_fields: 0,
dm_position: Point::default(),
dm_display_orientation: 0,
dm_display_fixed_output: 0,
dm_color: 0,
dm_duplex: 0,
dm_y_resolution: 0,
dm_tt_option: 0,
dm_collate: 0,
dm_form_name: [0; 32],
dm_log_pixels: 0,
dm_bits_per_pel: 0,
dm_pels_width: 0,
dm_pels_height: 0,
dm_display_flags: 0,
dm_display_frequency: 0,
dm_icm_method: 0,
dm_icm_intent: 0,
dm_media_type: 0,
dm_dither_type: 0,
dm_reserved1: 0,
dm_reserved2: 0,
dm_panning_width: 0,
dm_panning_height: 0,
}
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct Luid {
pub low_part: u32,
pub high_part: i32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct DisplayConfig2dRegion {
pub cx: u32,
pub cy: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct DisplayConfigRational {
pub numerator: u32,
pub denominator: u32,
}
impl DisplayConfigRational {
pub const fn millihertz(self, divider: u32) -> Option<u32> {
if self.numerator == 0 || self.denominator == 0 {
return None;
}
let denominator = if divider == 0 {
self.denominator
} else {
self.denominator.saturating_mul(divider)
};
if denominator == 0 {
return None;
}
Some(self.numerator.saturating_mul(1_000) / denominator)
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct DisplayConfigVideoSignalInfo {
pub pixel_rate: u64,
pub h_sync_freq: DisplayConfigRational,
pub v_sync_freq: DisplayConfigRational,
pub active_size: DisplayConfig2dRegion,
pub total_size: DisplayConfig2dRegion,
pub additional_signal_info: u32,
pub scan_line_ordering: i32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct DisplayConfigTargetMode {
pub target_video_signal_info: DisplayConfigVideoSignalInfo,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct DisplayConfigModeInfo {
pub info_type: i32,
pub id: u32,
pub adapter_id: Luid,
pub target_mode: DisplayConfigTargetMode,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct DisplayConfigPathSourceInfo {
pub adapter_id: Luid,
pub id: u32,
pub mode_info_idx: u32,
pub status_flags: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct DisplayConfigPathTargetInfo {
pub adapter_id: Luid,
pub id: u32,
pub mode_info_idx: u32,
pub output_technology: i32,
pub rotation: i32,
pub scaling: i32,
pub refresh_rate: DisplayConfigRational,
pub scan_line_ordering: i32,
pub target_available: Bool32,
pub status_flags: u32,
}
impl DisplayConfigPathTargetInfo {
pub const fn target_mode_index(self) -> Option<usize> {
let index = (self.mode_info_idx >> 16) as usize;
if index == value::DISPLAYCONFIG_PATH_TARGET_MODE_IDX_INVALID as usize {
None
} else {
Some(index)
}
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct DisplayConfigPathInfo {
pub source_info: DisplayConfigPathSourceInfo,
pub target_info: DisplayConfigPathTargetInfo,
pub flags: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct DisplayConfigDeviceInfoHeader {
pub kind: i32,
pub size: u32,
pub adapter_id: Luid,
pub id: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct DisplayConfigSourceDeviceName {
pub header: DisplayConfigDeviceInfoHeader,
pub view_gdi_device_name: [u16; 32],
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct TrackMouse {
pub cb_size: u32,
pub dw_flags: u32,
pub hwnd_track: Handle,
pub dw_hover_time: u32,
}
#[cfg(test)]
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct DropFiles {
pub p_files: u32,
pub pt: Point,
pub f_nc: Bool32,
pub f_wide: Bool32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct RawInputDevice {
pub us_usage_page: u16,
pub us_usage: u16,
pub dw_flags: u32,
pub hwnd_target: Handle,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct RawInputHeader {
pub dw_type: u32,
pub dw_size: u32,
pub h_device: Handle,
pub w_param: Wparam,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct RawMouse {
pub us_flags: u16,
pub padding: u16,
pub ul_buttons: u32,
pub ul_raw_buttons: u32,
pub l_last_x: i32,
pub l_last_y: i32,
pub ul_extra_information: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct CompositionForm {
pub dw_style: u32,
pub pt_current_pos: Point,
pub rc_area: Rect,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct CandidateForm {
pub dw_index: u32,
pub dw_style: u32,
pub pt_current_pos: Point,
pub rc_area: Rect,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct RawKeyboard {
pub make_code: u16,
pub flags: u16,
pub reserved: u16,
pub v_key: u16,
pub message: u32,
pub extra_information: u32,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub union RawInputData {
pub mouse: RawMouse,
pub keyboard: RawKeyboard,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct RawInput {
pub header: RawInputHeader,
pub data: RawInputData,
}
impl Default for RawInput {
fn default() -> Self {
Self {
header: RawInputHeader::default(),
data: RawInputData {
mouse: RawMouse::default(),
},
}
}
}
pub mod style {
pub const POPUP: u32 = 0x8000_0000;
pub const VISIBLE: u32 = 0x1000_0000;
pub const CLIP_SIBLINGS: u32 = 0x0400_0000;
pub const CLIP_CHILDREN: u32 = 0x0200_0000;
pub const CAPTION: u32 = 0x00C0_0000;
pub const SYS_MENU: u32 = 0x0008_0000;
pub const THICK_FRAME: u32 = 0x0004_0000;
pub const MINIMIZE_BOX: u32 = 0x0002_0000;
pub const MAXIMIZE_BOX: u32 = 0x0001_0000;
pub const OVERLAPPED_WINDOW: u32 =
CAPTION | SYS_MENU | THICK_FRAME | MINIMIZE_BOX | MAXIMIZE_BOX;
pub const EX_APP_WINDOW: u32 = 0x0004_0000;
pub const EX_WINDOW_EDGE: u32 = 0x0000_0100;
pub const EX_TOOL_WINDOW: u32 = 0x0000_0080;
pub const EX_TOPMOST: u32 = 0x0000_0008;
pub const EX_NO_ACTIVATE: u32 = 0x0800_0000;
pub const EX_NO_REDIRECTION_BITMAP: u32 = 0x0020_0000;
pub const EX_ACCEPT_FILES: u32 = 0x0000_0010;
}
pub mod dwm {
pub const WINDOW_CORNER_PREFERENCE: u32 = 33;
pub const CORNER_DEFAULT: u32 = 0;
pub const CORNER_DO_NOT_ROUND: u32 = 1;
pub const BORDER_COLOR: u32 = 34;
pub const COLOR_DEFAULT: u32 = 0xFFFF_FFFF;
pub const COLOR_NONE: u32 = 0xFFFF_FFFE;
}
pub mod appbar {
pub const NEW: u32 = 0x0000_0000;
pub const REMOVE: u32 = 0x0000_0001;
pub const QUERY_POS: u32 = 0x0000_0002;
pub const SET_POS: u32 = 0x0000_0003;
pub const ACTIVATE: u32 = 0x0000_0006;
pub const WINDOW_POS_CHANGED: u32 = 0x0000_0009;
pub const EDGE_LEFT: u32 = 0;
pub const EDGE_TOP: u32 = 1;
pub const EDGE_RIGHT: u32 = 2;
pub const EDGE_BOTTOM: u32 = 3;
pub const POS_CHANGED: u32 = 0x0000_0001;
pub const FULL_SCREEN_APP: u32 = 0x0000_0002;
}
pub mod msg {
pub const DESTROY: u32 = 0x0002;
pub const MOVE: u32 = 0x0003;
pub const SIZE: u32 = 0x0005;
pub const ACTIVATE: u32 = 0x0006;
pub const SET_FOCUS: u32 = 0x0007;
pub const KILL_FOCUS: u32 = 0x0008;
pub const CLOSE: u32 = 0x0010;
pub const ACTIVATE_APP: u32 = 0x001C;
pub const SET_CURSOR: u32 = 0x0020;
pub const NC_HIT_TEST: u32 = 0x0084;
pub const GET_MIN_MAX_INFO: u32 = 0x0024;
#[cfg(feature = "accesskit")]
pub const GET_OBJECT: u32 = 0x003D;
pub const DISPLAY_CHANGE: u32 = 0x007E;
pub const WINDOW_POS_CHANGED: u32 = 0x0047;
pub const SETTING_CHANGE: u32 = 0x001A;
pub const APP_BAR: u32 = 0x8001;
pub const NC_CREATE: u32 = 0x0081;
pub const NC_DESTROY: u32 = 0x0082;
pub const INPUT_DEVICE_CHANGE: u32 = 0x00FE;
pub const INPUT: u32 = 0x00FF;
pub const KEY_DOWN: u32 = 0x0100;
pub const KEY_UP: u32 = 0x0101;
pub const CHAR: u32 = 0x0102;
pub const SYS_KEY_DOWN: u32 = 0x0104;
pub const SYS_KEY_UP: u32 = 0x0105;
pub const IME_START_COMPOSITION: u32 = 0x010D;
pub const IME_END_COMPOSITION: u32 = 0x010E;
pub const IME_COMPOSITION: u32 = 0x010F;
pub const IME_SET_CONTEXT: u32 = 0x0281;
pub const SYS_COMMAND: u32 = 0x0112;
pub const MOUSE_MOVE: u32 = 0x0200;
pub const L_BUTTON_DOWN: u32 = 0x0201;
pub const L_BUTTON_UP: u32 = 0x0202;
pub const R_BUTTON_DOWN: u32 = 0x0204;
pub const R_BUTTON_UP: u32 = 0x0205;
pub const M_BUTTON_DOWN: u32 = 0x0207;
pub const M_BUTTON_UP: u32 = 0x0208;
pub const MOUSE_WHEEL: u32 = 0x020A;
pub const X_BUTTON_DOWN: u32 = 0x020B;
pub const X_BUTTON_UP: u32 = 0x020C;
pub const MOUSE_H_WHEEL: u32 = 0x020E;
pub const POINTER_UPDATE: u32 = 0x0245;
pub const POINTER_DOWN: u32 = 0x0246;
pub const POINTER_UP: u32 = 0x0247;
pub const POINTER_CAPTURE_CHANGED: u32 = 0x024C;
pub const SIZING: u32 = 0x0214;
pub const CAPTURE_CHANGED: u32 = 0x0215;
pub const DROP_FILES: u32 = 0x0233;
pub const EXIT_SIZE_MOVE: u32 = 0x0232;
pub const MOUSE_LEAVE: u32 = 0x02A3;
pub const DPI_CHANGED: u32 = 0x02E0;
}
pub mod value {
pub const SIZE_MINIMIZED: usize = 1;
pub const GWL_STYLE: i32 = -16;
pub const GWL_EX_STYLE: i32 = -20;
pub const GWLP_USERDATA: i32 = -21;
pub const SW_HIDE: i32 = 0;
pub const SW_SHOW_NORMAL: i32 = 1;
pub const SW_SHOW_NO_ACTIVATE: i32 = 4;
#[cfg(test)]
pub const SW_MINIMIZE: i32 = 6;
#[cfg(test)]
pub const SW_RESTORE: i32 = 9;
pub const SWP_NO_SIZE: u32 = 0x0001;
pub const SWP_NO_MOVE: u32 = 0x0002;
pub const SWP_NO_Z_ORDER: u32 = 0x0004;
pub const SWP_NO_ACTIVATE: u32 = 0x0010;
pub const SWP_FRAME_CHANGED: u32 = 0x0020;
pub const SWP_NO_OWNER_Z_ORDER: u32 = 0x0200;
pub const HWND_BOTTOM: isize = 1;
pub const HWND_TOPMOST: isize = -1;
pub const PM_REMOVE: u32 = 0x0001;
#[cfg(test)]
pub const PM_NOREMOVE: u32 = 0x0000;
pub const MONITOR_PRIMARY: u32 = 0x0000_0001;
pub const MONITOR_DEFAULT_TO_NEAREST: u32 = 0x0000_0002;
pub const HT_TRANSPARENT: isize = -1;
pub const SPI_SET_WORK_AREA: usize = 0x002F;
pub const MDT_EFFECTIVE_DPI: i32 = 0;
pub const ENUM_CURRENT_SETTINGS: u32 = 0xFFFF_FFFF;
pub const QDC_ONLY_ACTIVE_PATHS: u32 = 0x0000_0002;
pub const DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME: i32 = 1;
pub const DISPLAYCONFIG_MODE_INFO_TYPE_TARGET: i32 = 2;
pub const DISPLAYCONFIG_PATH_TARGET_MODE_IDX_INVALID: u32 = 0xffff;
pub const ERROR_SUCCESS: i32 = 0;
pub const DPI_PER_MONITOR_AWARE_V2: isize = -4;
pub const DEFAULT_DPI: u32 = 96;
pub const CW_USE_DEFAULT: i32 = i32::MIN;
pub const IDC_ARROW: usize = 32_512;
pub const IDC_IBEAM: usize = 32_513;
pub const IDC_WAIT: usize = 32_514;
pub const IDC_CROSS: usize = 32_515;
pub const IDC_SIZE_NWSE: usize = 32_642;
pub const IDC_SIZE_NESW: usize = 32_643;
pub const IDC_SIZE_WE: usize = 32_644;
pub const IDC_SIZE_NS: usize = 32_645;
pub const IDC_SIZE_ALL: usize = 32_646;
pub const IDC_NO: usize = 32_648;
pub const IDC_HAND: usize = 32_649;
pub const IDC_APP_STARTING: usize = 32_650;
pub const BLACK_BRUSH: i32 = 4;
pub const RGN_OR: i32 = 2;
pub const REGION_ERROR: i32 = 0;
pub const CS_REDRAW: u32 = 0x0002 | 0x0001;
pub const ERROR_ACCESS_DENIED: u32 = 5;
pub const ERROR_CLASS_ALREADY_EXISTS: u32 = 1410;
#[cfg(test)]
pub const QS_ALL_INPUT: u32 = 0x04FF;
pub const QS_ALL_EVENTS: u32 = 0x04BF;
pub const INFINITE: u32 = 0xFFFF_FFFF;
pub const WAIT_OBJECT_0: u32 = 0;
pub const CREATE_WAITABLE_TIMER_HIGH_RESOLUTION: u32 = 0x0000_0002;
pub const TIMER_SET_AND_WAIT: u32 = 0x0000_0002 | 0x0010_0000;
pub const WAIT_TIMEOUT: u32 = 258;
pub const WAIT_FAILED: u32 = 0xFFFF_FFFF;
pub const HT_CLIENT: u32 = 1;
pub const TME_LEAVE: u32 = 0x0000_0002;
pub const SC_KEY_MENU: usize = 0xF100;
pub const SC_COMMAND_MASK: usize = 0xFFF0;
pub const XBUTTON1: u32 = 0x0001;
pub const XBUTTON2: u32 = 0x0002;
pub const WHEEL_DELTA: i16 = 120;
pub const PT_TOUCH: u32 = 2;
pub const POINTER_MESSAGE_FLAG_IN_CONTACT: u32 = 0x0004;
pub const POINTER_MESSAGE_FLAG_PRIMARY: u32 = 0x2000;
pub const POINTER_MESSAGE_FLAG_CANCELED: u32 = 0x8000;
pub const HID_USAGE_PAGE_GENERIC: u16 = 0x01;
pub const HID_USAGE_GENERIC_MOUSE: u16 = 0x02;
pub const HID_USAGE_GENERIC_KEYBOARD: u16 = 0x06;
pub const RIDEV_DEV_NOTIFY: u32 = 0x0000_2000;
pub const RID_INPUT: u32 = 0x1000_0003;
pub const RIDI_DEVICE_NAME: u32 = 0x2000_0007;
pub const RIM_TYPE_MOUSE: u32 = 0;
pub const RIM_TYPE_KEYBOARD: u32 = 1;
pub const RI_KEY_BREAK: u16 = 0x0001;
pub const RI_KEY_E0: u16 = 0x0002;
pub const RI_KEY_E1: u16 = 0x0004;
pub const RI_MOUSE_LEFT_BUTTON_DOWN: u16 = 0x0001;
pub const RI_MOUSE_RIGHT_BUTTON_DOWN: u16 = 0x0004;
pub const RI_MOUSE_MIDDLE_BUTTON_DOWN: u16 = 0x0010;
pub const RI_MOUSE_BUTTON_4_DOWN: u16 = 0x0040;
pub const RI_MOUSE_BUTTON_5_DOWN: u16 = 0x0100;
pub const RI_MOUSE_WHEEL: u16 = 0x0400;
pub const RI_MOUSE_H_WHEEL: u16 = 0x0800;
pub const GIDC_REMOVAL: usize = 2;
pub const GCS_COMP_STR: u32 = 0x0008;
pub const ISC_SHOW_UI_COMPOSITION_WINDOW: u32 = 0x8000_0000;
pub const GCS_CURSOR_POS: u32 = 0x0080;
pub const GCS_RESULT_STR: u32 = 0x0800;
pub const IACE_DEFAULT: u32 = 0x0010;
pub const CFS_DEFAULT: u32 = 0x0000;
pub const CFS_POINT: u32 = 0x0002;
pub const CFS_EXCLUDE: u32 = 0x0080;
pub const MOUSE_MOVE_ABSOLUTE: u16 = 0x0001;
pub const MOUSE_VIRTUAL_DESKTOP: u16 = 0x0002;
pub const ABSOLUTE_RANGE: i32 = 65_535;
pub const SM_CX_SCREEN: i32 = 0;
pub const SM_CY_SCREEN: i32 = 1;
#[cfg(test)]
pub const SM_X_VIRTUAL_SCREEN: i32 = 76;
#[cfg(test)]
pub const SM_Y_VIRTUAL_SCREEN: i32 = 77;
pub const SM_CX_VIRTUAL_SCREEN: i32 = 78;
pub const SM_CY_VIRTUAL_SCREEN: i32 = 79;
pub const SM_CX_ICON: i32 = 11;
pub const SM_CX_SM_ICON: i32 = 49;
pub const RT_GROUP_ICON: usize = 14;
pub const IMAGE_ICON: u32 = 1;
#[cfg(test)]
pub const LOAD_AS_RESOURCES: u32 = 0x0000_0022;
pub const CF_UNICODETEXT: u32 = 13;
pub const CF_HDROP: u32 = 15;
pub const GMEM_MOVEABLE: u32 = 0x0002;
pub const DRAG_QUERY_COUNT: u32 = 0xFFFF_FFFF;
pub const MAPVK_VK_TO_CHAR: u32 = 2;
pub const MAPVK_VK_TO_VSC_EX: u32 = 4;
pub const VK_L_SHIFT: usize = 0xA0;
pub const VK_R_SHIFT: usize = 0xA1;
pub const VK_L_CONTROL: usize = 0xA2;
pub const VK_R_CONTROL: usize = 0xA3;
pub const VK_L_MENU: usize = 0xA4;
pub const VK_R_MENU: usize = 0xA5;
pub const VK_SHIFT: usize = 0x10;
pub const VK_CONTROL: usize = 0x11;
pub const VK_MENU: usize = 0x12;
pub const VK_L_WIN: usize = 0x5B;
pub const VK_R_WIN: usize = 0x5C;
pub const VK_CAPITAL: usize = 0x14;
pub const VK_NUM_LOCK: usize = 0x90;
pub const VK_PROCESS_KEY: u16 = 0xE5;
pub const WMSZ_LEFT: usize = 1;
pub const WMSZ_RIGHT: usize = 2;
pub const WMSZ_TOP: usize = 3;
pub const WMSZ_TOP_LEFT: usize = 4;
pub const WMSZ_TOP_RIGHT: usize = 5;
pub const WMSZ_BOTTOM: usize = 6;
pub const WMSZ_BOTTOM_LEFT: usize = 7;
pub const WMSZ_BOTTOM_RIGHT: usize = 8;
}
#[cfg(target_os = "windows")]
#[link(name = "user32")]
unsafe extern "system" {
pub fn RegisterClassExW(class: *const WndClassExW) -> u16;
pub fn CreateWindowExW(
ex_style: u32,
class_name: *const u16,
window_name: *const u16,
style: u32,
x: i32,
y: i32,
width: i32,
height: i32,
parent: Handle,
menu: Handle,
instance: Handle,
param: *mut c_void,
) -> Handle;
pub fn DestroyWindow(hwnd: Handle) -> Bool32;
pub fn DefWindowProcW(hwnd: Handle, message: u32, w_param: Wparam, l_param: Lparam) -> Lresult;
pub fn GetWindowLongPtrW(hwnd: Handle, index: i32) -> isize;
pub fn SetWindowLongPtrW(hwnd: Handle, index: i32, value: isize) -> isize;
pub fn ShowWindow(hwnd: Handle, command: i32) -> Bool32;
pub fn IsWindowVisible(hwnd: Handle) -> Bool32;
pub fn IsIconic(hwnd: Handle) -> Bool32;
pub fn SetWindowTextW(hwnd: Handle, text: *const u16) -> Bool32;
pub fn SetWindowPos(
hwnd: Handle,
insert_after: Handle,
x: i32,
y: i32,
width: i32,
height: i32,
flags: u32,
) -> Bool32;
pub fn GetWindowPlacement(hwnd: Handle, placement: *mut WindowPlacement) -> Bool32;
pub fn SetWindowPlacement(hwnd: Handle, placement: *const WindowPlacement) -> Bool32;
pub fn GetClientRect(hwnd: Handle, rect: *mut Rect) -> Bool32;
pub fn AdjustWindowRectExForDpi(
rect: *mut Rect,
style: u32,
menu: Bool32,
ex_style: u32,
dpi: u32,
) -> Bool32;
pub fn PeekMessageW(
message: *mut Msg,
hwnd: Handle,
filter_min: u32,
filter_max: u32,
remove: u32,
) -> Bool32;
pub fn TranslateMessage(message: *const Msg) -> Bool32;
pub fn DispatchMessageW(message: *const Msg) -> Lresult;
#[cfg(test)]
pub fn SendMessageW(hwnd: Handle, message: u32, w_param: Wparam, l_param: Lparam) -> Lresult;
#[cfg(test)]
pub fn PostMessageW(hwnd: Handle, message: u32, w_param: Wparam, l_param: Lparam) -> Bool32;
pub fn MsgWaitForMultipleObjectsEx(
count: u32,
handles: *const Handle,
milliseconds: u32,
wake_mask: u32,
flags: u32,
) -> u32;
#[cfg(test)]
pub fn GetQueueStatus(flags: u32) -> u32;
pub fn MonitorFromWindow(hwnd: Handle, flags: u32) -> Handle;
pub fn MonitorFromPoint(point: Point, flags: u32) -> Handle;
pub fn GetWindowRect(hwnd: Handle, rect: *mut Rect) -> Bool32;
pub fn EnumDisplayMonitors(
hdc: Handle,
clip: *const Rect,
callback: MonitorEnumProc,
data: Lparam,
) -> Bool32;
pub fn GetMonitorInfoW(monitor: Handle, info: *mut MonitorInfoExW) -> Bool32;
pub fn EnumDisplaySettingsW(device: *const u16, mode: u32, dev_mode: *mut DevModeW) -> Bool32;
pub fn GetDisplayConfigBufferSizes(
flags: u32,
path_count: *mut u32,
mode_count: *mut u32,
) -> i32;
pub fn QueryDisplayConfig(
flags: u32,
path_count: *mut u32,
paths: *mut DisplayConfigPathInfo,
mode_count: *mut u32,
modes: *mut DisplayConfigModeInfo,
topology: *mut u32,
) -> i32;
pub fn DisplayConfigGetDeviceInfo(request: *mut DisplayConfigDeviceInfoHeader) -> i32;
pub fn GetDpiForWindow(hwnd: Handle) -> u32;
pub fn SetProcessDpiAwarenessContext(context: isize) -> Bool32;
pub fn LoadCursorW(instance: Handle, name: usize) -> Handle;
pub fn GetMessageTime() -> i32;
pub fn TrackMouseEvent(track: *mut TrackMouse) -> Bool32;
pub fn SetCapture(hwnd: Handle) -> Handle;
pub fn ReleaseCapture() -> Bool32;
pub fn ClipCursor(rect: *const Rect) -> Bool32;
#[cfg(test)]
pub fn GetClipCursor(rect: *mut Rect) -> Bool32;
pub fn SetForegroundWindow(hwnd: Handle) -> Bool32;
pub fn GetForegroundWindow() -> Handle;
#[cfg(feature = "accesskit")]
pub fn GetFocus() -> Handle;
pub fn ClientToScreen(hwnd: Handle, point: *mut Point) -> Bool32;
pub fn ScreenToClient(hwnd: Handle, point: *mut Point) -> Bool32;
pub fn SetWindowRgn(hwnd: Handle, region: Handle, redraw: Bool32) -> i32;
pub fn GetPointerType(pointer_id: u32, kind: *mut u32) -> Bool32;
pub fn SetCursorPos(x: i32, y: i32) -> Bool32;
pub fn GetCursorPos(point: *mut Point) -> Bool32;
pub fn SetCursor(cursor: Handle) -> Handle;
pub fn ShowCursor(show: Bool32) -> i32;
pub fn GetKeyboardState(state: *mut u8) -> Bool32;
pub fn MapVirtualKeyW(code: u32, map_type: u32) -> u32;
pub fn RegisterRawInputDevices(devices: *const RawInputDevice, count: u32, size: u32)
-> Bool32;
pub fn GetRawInputData(
raw_input: Handle,
command: u32,
data: *mut c_void,
size: *mut u32,
header_size: u32,
) -> u32;
pub fn GetRawInputDeviceInfoW(
device: Handle,
command: u32,
data: *mut c_void,
size: *mut u32,
) -> u32;
pub fn GetSystemMetrics(index: i32) -> i32;
pub fn LoadImageW(
instance: Handle,
name: *const u16,
kind: u32,
width: i32,
height: i32,
flags: u32,
) -> Handle;
#[cfg(test)]
pub fn DestroyIcon(icon: Handle) -> Bool32;
pub fn RegisterClipboardFormatW(name: *const u16) -> u32;
pub fn OpenClipboard(hwnd: Handle) -> Bool32;
pub fn CloseClipboard() -> Bool32;
pub fn EmptyClipboard() -> Bool32;
pub fn SetClipboardData(format: u32, mem: Handle) -> Handle;
pub fn GetClipboardData(format: u32) -> Handle;
#[cfg(test)]
pub fn GetOpenClipboardWindow() -> Handle;
}
#[cfg(target_os = "windows")]
#[link(name = "shell32")]
unsafe extern "system" {
pub fn DragAcceptFiles(hwnd: Handle, accept: Bool32);
pub fn SHAppBarMessage(message: u32, data: *mut AppBarData) -> usize;
pub fn DragQueryFileW(hdrop: Handle, index: u32, buffer: *mut u16, size: u32) -> u32;
pub fn DragQueryPoint(hdrop: Handle, point: *mut Point) -> Bool32;
pub fn DragFinish(hdrop: Handle);
}
#[cfg(target_os = "windows")]
#[link(name = "imm32")]
unsafe extern "system" {
pub fn ImmGetContext(hwnd: Handle) -> Handle;
pub fn ImmReleaseContext(hwnd: Handle, context: Handle) -> Bool32;
pub fn ImmGetCompositionStringW(
context: Handle,
index: u32,
buffer: *mut c_void,
size: u32,
) -> i32;
pub fn ImmSetCompositionWindow(context: Handle, form: *const CompositionForm) -> Bool32;
pub fn ImmSetCandidateWindow(context: Handle, form: *const CandidateForm) -> Bool32;
pub fn ImmAssociateContextEx(hwnd: Handle, context: Handle, flags: u32) -> Bool32;
}
#[cfg(target_os = "windows")]
#[link(name = "dwmapi")]
unsafe extern "system" {
pub fn DwmSetWindowAttribute(
hwnd: Handle,
attribute: u32,
value: *const c_void,
size: u32,
) -> i32;
}
#[cfg(target_os = "windows")]
#[link(name = "gdi32")]
unsafe extern "system" {
pub fn GetStockObject(object: i32) -> Handle;
pub fn CreateRectRgn(left: i32, top: i32, right: i32, bottom: i32) -> Handle;
pub fn CombineRgn(destination: Handle, first: Handle, second: Handle, mode: i32) -> i32;
pub fn DeleteObject(object: Handle) -> Bool32;
}
#[cfg(target_os = "windows")]
#[link(name = "shcore")]
unsafe extern "system" {
pub fn GetDpiForMonitor(
monitor: Handle,
dpi_type: i32,
dpi_x: *mut u32,
dpi_y: *mut u32,
) -> i32;
}
#[cfg(target_os = "windows")]
#[link(name = "kernel32")]
unsafe extern "system" {
pub fn GetModuleHandleW(name: *const u16) -> Handle;
pub fn GetLastError() -> u32;
pub fn EnumResourceNamesW(
module: Handle,
kind: *const u16,
callback: EnumResNameProc,
param: Lparam,
) -> Bool32;
#[cfg(test)]
pub fn LoadLibraryExW(name: *const u16, file: Handle, flags: u32) -> Handle;
#[cfg(test)]
pub fn FreeLibrary(module: Handle) -> Bool32;
pub fn GlobalAlloc(flags: u32, bytes: usize) -> Handle;
pub fn GlobalFree(mem: Handle) -> Handle;
pub fn GlobalLock(mem: Handle) -> *mut c_void;
pub fn GlobalUnlock(mem: Handle) -> Bool32;
pub fn GlobalSize(mem: Handle) -> usize;
pub fn GetTickCount64() -> u64;
pub fn CreateWaitableTimerExW(
attributes: *const c_void,
name: *const u16,
flags: u32,
access: u32,
) -> Handle;
pub fn SetWaitableTimer(
timer: Handle,
due: *const i64,
period: i32,
completion: *const c_void,
argument: *const c_void,
resume: Bool32,
) -> Bool32;
pub fn CloseHandle(handle: Handle) -> Bool32;
pub fn CreateEventW(
attributes: *const c_void,
manual_reset: Bool32,
initial_state: Bool32,
name: *const u16,
) -> Handle;
pub fn SetEvent(event: Handle) -> Bool32;
}
pub fn wide(text: &str) -> Option<Vec<u16>> {
if text.as_bytes().contains(&0) {
return None;
}
let mut buffer: Vec<u16> = text.encode_utf16().collect();
buffer.push(0);
Some(buffer)
}
#[cfg(target_os = "windows")]
pub fn tick_nanos() -> u64 {
unsafe { GetTickCount64() }.saturating_mul(1_000_000)
}
#[cfg(test)]
mod tests {
use super::*;
fn field_size<T, F>(_select: fn(&T) -> &F) -> usize {
size_of::<F>()
}
macro_rules! assert_layout {
($ty:ident, $size:literal, { $($field:ident: $offset:literal, $width:literal;)+ }) => {{
let _every_field_has_a_row: fn($ty) = |value| {
let $ty { $($field: _),+ } = value;
};
assert_eq!(size_of::<$ty>(), $size, concat!("size of ", stringify!($ty)));
$(
assert_eq!(
core::mem::offset_of!($ty, $field),
$offset,
concat!("offset of ", stringify!($ty), "::", stringify!($field))
);
assert_eq!(
field_size(|value: &$ty| &value.$field),
$width,
concat!("width of ", stringify!($ty), "::", stringify!($field))
);
)+
}};
}
#[test]
fn the_structures_match_the_c_layout() {
assert_layout!(Rect, 16, {
left: 0, 4;
top: 4, 4;
right: 8, 4;
bottom: 12, 4;
});
assert_layout!(Point, 8, {
x: 0, 4;
y: 4, 4;
});
assert_layout!(Msg, 48, {
hwnd: 0, 8;
message: 8, 4;
w_param: 16, 8;
l_param: 24, 8;
time: 32, 4;
pt: 36, 8;
l_private: 44, 4;
});
assert_layout!(WndClassExW, 80, {
cb_size: 0, 4;
style: 4, 4;
lpfn_wnd_proc: 8, 8;
cb_cls_extra: 16, 4;
cb_wnd_extra: 20, 4;
h_instance: 24, 8;
h_icon: 32, 8;
h_cursor: 40, 8;
hbr_background: 48, 8;
lpsz_menu_name: 56, 8;
lpsz_class_name: 64, 8;
h_icon_sm: 72, 8;
});
assert_layout!(CreateStructW, 80, {
lp_create_params: 0, 8;
h_instance: 8, 8;
h_menu: 16, 8;
hwnd_parent: 24, 8;
cy: 32, 4;
cx: 36, 4;
y: 40, 4;
x: 44, 4;
style: 48, 4;
lpsz_name: 56, 8;
lpsz_class: 64, 8;
dw_ex_style: 72, 4;
});
assert_layout!(MinMaxInfo, 40, {
pt_reserved: 0, 8;
pt_max_size: 8, 8;
pt_max_position: 16, 8;
pt_min_track_size: 24, 8;
pt_max_track_size: 32, 8;
});
assert_layout!(WindowPlacement, 44, {
length: 0, 4;
flags: 4, 4;
show_cmd: 8, 4;
pt_min_position: 12, 8;
pt_max_position: 20, 8;
rc_normal_position: 28, 16;
});
assert_layout!(MonitorInfoExW, 104, {
cb_size: 0, 4;
rc_monitor: 4, 16;
rc_work: 20, 16;
dw_flags: 36, 4;
sz_device: 40, 64;
});
assert_layout!(DevModeW, 220, {
dm_device_name: 0, 64;
dm_spec_version: 64, 2;
dm_driver_version: 66, 2;
dm_size: 68, 2;
dm_driver_extra: 70, 2;
dm_fields: 72, 4;
dm_position: 76, 8;
dm_display_orientation: 84, 4;
dm_display_fixed_output: 88, 4;
dm_color: 92, 2;
dm_duplex: 94, 2;
dm_y_resolution: 96, 2;
dm_tt_option: 98, 2;
dm_collate: 100, 2;
dm_form_name: 102, 64;
dm_log_pixels: 166, 2;
dm_bits_per_pel: 168, 4;
dm_pels_width: 172, 4;
dm_pels_height: 176, 4;
dm_display_flags: 180, 4;
dm_display_frequency: 184, 4;
dm_icm_method: 188, 4;
dm_icm_intent: 192, 4;
dm_media_type: 196, 4;
dm_dither_type: 200, 4;
dm_reserved1: 204, 4;
dm_reserved2: 208, 4;
dm_panning_width: 212, 4;
dm_panning_height: 216, 4;
});
assert_layout!(Luid, 8, {
low_part: 0, 4;
high_part: 4, 4;
});
assert_layout!(DisplayConfig2dRegion, 8, {
cx: 0, 4;
cy: 4, 4;
});
assert_layout!(DisplayConfigRational, 8, {
numerator: 0, 4;
denominator: 4, 4;
});
assert_layout!(DisplayConfigVideoSignalInfo, 48, {
pixel_rate: 0, 8;
h_sync_freq: 8, 8;
v_sync_freq: 16, 8;
active_size: 24, 8;
total_size: 32, 8;
additional_signal_info: 40, 4;
scan_line_ordering: 44, 4;
});
assert_layout!(DisplayConfigTargetMode, 48, {
target_video_signal_info: 0, 48;
});
assert_layout!(DisplayConfigModeInfo, 64, {
info_type: 0, 4;
id: 4, 4;
adapter_id: 8, 8;
target_mode: 16, 48;
});
assert_layout!(DisplayConfigPathSourceInfo, 20, {
adapter_id: 0, 8;
id: 8, 4;
mode_info_idx: 12, 4;
status_flags: 16, 4;
});
assert_layout!(DisplayConfigPathTargetInfo, 48, {
adapter_id: 0, 8;
id: 8, 4;
mode_info_idx: 12, 4;
output_technology: 16, 4;
rotation: 20, 4;
scaling: 24, 4;
refresh_rate: 28, 8;
scan_line_ordering: 36, 4;
target_available: 40, 4;
status_flags: 44, 4;
});
assert_layout!(DisplayConfigPathInfo, 72, {
source_info: 0, 20;
target_info: 20, 48;
flags: 68, 4;
});
assert_layout!(DisplayConfigDeviceInfoHeader, 20, {
kind: 0, 4;
size: 4, 4;
adapter_id: 8, 8;
id: 16, 4;
});
assert_layout!(DisplayConfigSourceDeviceName, 84, {
header: 0, 20;
view_gdi_device_name: 20, 64;
});
assert_layout!(TrackMouse, 24, {
cb_size: 0, 4;
dw_flags: 4, 4;
hwnd_track: 8, 8;
dw_hover_time: 16, 4;
});
assert_layout!(RawInputDevice, 16, {
us_usage_page: 0, 2;
us_usage: 2, 2;
dw_flags: 4, 4;
hwnd_target: 8, 8;
});
assert_layout!(RawInputHeader, 24, {
dw_type: 0, 4;
dw_size: 4, 4;
h_device: 8, 8;
w_param: 16, 8;
});
assert_layout!(RawMouse, 24, {
us_flags: 0, 2;
padding: 2, 2;
ul_buttons: 4, 4;
ul_raw_buttons: 8, 4;
l_last_x: 12, 4;
l_last_y: 16, 4;
ul_extra_information: 20, 4;
});
assert_layout!(RawKeyboard, 16, {
make_code: 0, 2;
flags: 2, 2;
reserved: 4, 2;
v_key: 6, 2;
message: 8, 4;
extra_information: 12, 4;
});
assert_layout!(RawInput, 48, {
header: 0, 24;
data: 24, 24;
});
assert_eq!(size_of::<RawInputData>(), 24);
assert_eq!(core::mem::offset_of!(RawInput, data.mouse), 24);
assert_eq!(core::mem::offset_of!(RawInput, data.keyboard), 24);
assert!(size_of::<RawKeyboard>() <= size_of::<RawMouse>());
assert_layout!(CompositionForm, 28, {
dw_style: 0, 4;
pt_current_pos: 4, 8;
rc_area: 12, 16;
});
assert_layout!(CandidateForm, 32, {
dw_index: 0, 4;
dw_style: 4, 4;
pt_current_pos: 8, 8;
rc_area: 16, 16;
});
assert_layout!(DropFiles, 20, {
p_files: 0, 4;
pt: 4, 8;
f_nc: 12, 4;
f_wide: 16, 4;
});
}
#[test]
fn the_defaults_carry_the_sizes_the_system_validates() {
assert_eq!(
u32::from(DevModeW::default().dm_size),
size_of::<DevModeW>() as u32
);
assert_eq!(
MonitorInfoExW::default().cb_size,
size_of::<MonitorInfoExW>() as u32
);
}
#[test]
fn a_rectangle_is_two_corners_and_never_has_a_negative_size() {
let rect = Rect {
left: 100,
top: 50,
right: 1380,
bottom: 770,
};
assert_eq!(rect.width(), 1280);
assert_eq!(rect.height(), 720);
let inverted = Rect {
left: 10,
top: 10,
right: 0,
bottom: 0,
};
assert_eq!(inverted.width(), 0);
assert_eq!(inverted.height(), 0);
}
#[test]
fn an_intersection_is_the_overlap_and_is_degenerate_when_there_is_none() {
let client = Rect {
left: 8,
top: 31,
right: 1036,
bottom: 751,
};
let screen = Rect {
left: 0,
top: 0,
right: 1024,
bottom: 768,
};
assert_eq!(
client.intersect(screen),
Rect {
left: 8,
top: 31,
right: 1024,
bottom: 751
},
"only the edge that overhangs moves"
);
assert_eq!(
client.intersect(client),
client,
"a window that fits is not clamped at all"
);
let left_monitor = Rect {
left: -1920,
top: 0,
right: -900,
bottom: 1080,
};
let virtual_screen = Rect {
left: -1920,
top: 0,
right: 1920,
bottom: 1080,
};
assert_eq!(left_monitor.intersect(virtual_screen), left_monitor);
let elsewhere = Rect {
left: 4_000,
top: 4_000,
right: 5_000,
bottom: 5_000,
};
let empty = client.intersect(elsewhere);
assert_eq!((empty.width(), empty.height()), (0, 0));
}
#[test]
fn a_string_with_an_interior_nul_has_no_utf16_form() {
assert_eq!(
wide("crcbl"),
Some(vec![0x0063, 0x0072, 0x0063, 0x0062, 0x006C, 0])
);
assert_eq!(wide(""), Some(vec![0]));
assert_eq!(wide("🎮").map(|text| text.len()), Some(3));
assert_eq!(wide("save\0nothing"), None);
}
#[test]
fn the_overlapped_window_style_is_the_sum_of_its_parts() {
assert_eq!(style::OVERLAPPED_WINDOW, 0x00CF_0000);
assert_eq!(style::CAPTION, 0x00C0_0000);
assert_eq!(value::CS_REDRAW, 0x0003);
}
#[test]
fn the_transparency_values_are_the_sdks() {
assert_eq!(style::EX_NO_REDIRECTION_BITMAP, 0x0020_0000);
assert_eq!(dwm::WINDOW_CORNER_PREFERENCE, 33);
assert_eq!(dwm::CORNER_DEFAULT, 0);
assert_eq!(dwm::CORNER_DO_NOT_ROUND, 1);
assert_eq!(dwm::BORDER_COLOR, 34);
assert_eq!(dwm::COLOR_DEFAULT, 0xFFFF_FFFF);
assert_eq!(dwm::COLOR_NONE, 0xFFFF_FFFE);
assert_eq!(value::RGN_OR, 2);
assert_eq!(value::REGION_ERROR, 0);
}
#[test]
fn a_rational_and_a_mode_index_convert_exactly() {
let ntsc = DisplayConfigRational {
numerator: 60_000,
denominator: 1_001,
};
assert_eq!(ntsc.millihertz(0), Some(59_940));
let sixty = DisplayConfigRational {
numerator: 60_000,
denominator: 1_000,
};
assert_eq!(sixty.millihertz(0), Some(60_000));
assert_eq!(sixty.millihertz(2), Some(30_000));
assert_eq!(DisplayConfigRational::default().millihertz(0), None);
assert_eq!(
DisplayConfigRational {
numerator: 1,
denominator: 0
}
.millihertz(0),
None
);
let with_mode = DisplayConfigPathTargetInfo {
mode_info_idx: 0x0003_0005, ..Default::default()
};
assert_eq!(with_mode.target_mode_index(), Some(3));
let without = DisplayConfigPathTargetInfo {
mode_info_idx: 0xFFFF_0000, ..Default::default()
};
assert_eq!(without.target_mode_index(), None);
}
}
#[cfg(all(test, target_os = "windows"))]
mod sdk_layout;