rusty_duplication/
ext.rs

1use windows::Win32::Graphics::{
2  Dxgi::{DXGI_OUTDUPL_DESC, DXGI_OUTDUPL_FRAME_INFO, DXGI_OUTPUT_DESC},
3  Gdi::MONITORINFO,
4};
5
6pub trait OutputDescExt {
7  fn width(&self) -> u32;
8  fn height(&self) -> u32;
9}
10
11impl OutputDescExt for DXGI_OUTPUT_DESC {
12  #[inline]
13  fn width(&self) -> u32 {
14    (self.DesktopCoordinates.right - self.DesktopCoordinates.left) as u32
15  }
16  #[inline]
17  fn height(&self) -> u32 {
18    (self.DesktopCoordinates.bottom - self.DesktopCoordinates.top) as u32
19  }
20}
21
22pub trait OutDuplDescExt {
23  fn calc_buffer_size(&self) -> usize;
24}
25
26impl OutDuplDescExt for DXGI_OUTDUPL_DESC {
27  /// Return needed buffer size, in bytes.
28  #[inline]
29  fn calc_buffer_size(&self) -> usize {
30    (self.ModeDesc.Width * self.ModeDesc.Height * 4) as usize // 4 for BGRA32
31  }
32}
33
34pub trait FrameInfoExt {
35  fn desktop_updated(&self) -> bool;
36  /// Return `true` if the position or shape of the mouse was updated.
37  fn mouse_updated(&self) -> bool;
38  fn pointer_shape_updated(&self) -> bool;
39}
40
41impl FrameInfoExt for DXGI_OUTDUPL_FRAME_INFO {
42  #[inline]
43  fn desktop_updated(&self) -> bool {
44    self.LastPresentTime != 0
45  }
46
47  #[inline]
48  fn mouse_updated(&self) -> bool {
49    self.LastMouseUpdateTime != 0
50  }
51
52  #[inline]
53  fn pointer_shape_updated(&self) -> bool {
54    self.PointerShapeBufferSize > 0
55  }
56}
57
58pub trait MonitorInfoExt {
59  fn is_primary(&self) -> bool;
60}
61
62impl MonitorInfoExt for MONITORINFO {
63  #[inline]
64  fn is_primary(&self) -> bool {
65    self.dwFlags == 0x01 // MONITORINFOF_PRIMARY
66  }
67}
68
69#[cfg(test)]
70mod tests {
71  use super::*;
72  use windows::Win32::Graphics::{
73    Dxgi::{DXGI_OUTDUPL_DESC, DXGI_OUTDUPL_FRAME_INFO, DXGI_OUTPUT_DESC},
74    Gdi::MONITORINFO,
75  };
76
77  #[test]
78  fn output_desc_ext() {
79    let mut desc = DXGI_OUTPUT_DESC::default();
80    desc.DesktopCoordinates.left = 0;
81    desc.DesktopCoordinates.top = 0;
82    desc.DesktopCoordinates.right = 1920;
83    desc.DesktopCoordinates.bottom = 1080;
84    assert_eq!(desc.width(), 1920);
85    assert_eq!(desc.height(), 1080);
86  }
87
88  #[test]
89  fn out_dupl_desc_ext() {
90    let mut desc = DXGI_OUTDUPL_DESC::default();
91    desc.ModeDesc.Width = 1920;
92    desc.ModeDesc.Height = 1080;
93    assert_eq!(desc.calc_buffer_size(), 1920 * 1080 * 4);
94  }
95
96  #[test]
97  fn frame_info_ext() {
98    let mut desc = DXGI_OUTDUPL_FRAME_INFO::default();
99    assert!(!desc.desktop_updated());
100    desc.LastPresentTime = 1;
101    assert!(desc.desktop_updated());
102    assert!(!desc.mouse_updated());
103    desc.LastMouseUpdateTime = 1;
104    assert!(desc.mouse_updated());
105    assert!(!desc.pointer_shape_updated());
106    desc.PointerShapeBufferSize = 1;
107    assert!(desc.pointer_shape_updated());
108  }
109
110  #[test]
111  fn monitor_info_ext() {
112    let mut info = MONITORINFO::default();
113    assert!(!info.is_primary());
114    info.dwFlags = 0x01;
115    assert!(info.is_primary());
116  }
117}