xref: /aosp_15_r20/external/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef MODULES_DESKTOP_CAPTURE_WIN_SCREEN_CAPTURER_WIN_MAGNIFIER_H_
12 #define MODULES_DESKTOP_CAPTURE_WIN_SCREEN_CAPTURER_WIN_MAGNIFIER_H_
13 
14 #include <magnification.h>
15 #include <wincodec.h>
16 #include <windows.h>
17 
18 #include <memory>
19 
20 #include "modules/desktop_capture/desktop_capturer.h"
21 #include "modules/desktop_capture/screen_capture_frame_queue.h"
22 #include "modules/desktop_capture/screen_capturer_helper.h"
23 #include "modules/desktop_capture/shared_desktop_frame.h"
24 #include "modules/desktop_capture/win/scoped_thread_desktop.h"
25 
26 namespace webrtc {
27 
28 class DesktopFrame;
29 class DesktopRect;
30 
31 // Captures the screen using the Magnification API to support window exclusion.
32 // Each capturer must run on a dedicated thread because it uses thread local
33 // storage for redirecting the library callback. Also the thread must have a UI
34 // message loop to handle the window messages for the magnifier window.
35 //
36 // This class does not detect DesktopFrame::updated_region(), the field is
37 // always set to the entire frame rectangle. ScreenCapturerDifferWrapper should
38 // be used if that functionality is necessary.
39 class ScreenCapturerWinMagnifier : public DesktopCapturer {
40  public:
41   ScreenCapturerWinMagnifier();
42   ~ScreenCapturerWinMagnifier() override;
43 
44   ScreenCapturerWinMagnifier(const ScreenCapturerWinMagnifier&) = delete;
45   ScreenCapturerWinMagnifier& operator=(const ScreenCapturerWinMagnifier&) =
46       delete;
47 
48   // Overridden from ScreenCapturer:
49   void Start(Callback* callback) override;
50   void SetSharedMemoryFactory(
51       std::unique_ptr<SharedMemoryFactory> shared_memory_factory) override;
52   void CaptureFrame() override;
53   bool GetSourceList(SourceList* screens) override;
54   bool SelectSource(SourceId id) override;
55   void SetExcludedWindow(WindowId window) override;
56 
57  private:
58   typedef BOOL(WINAPI* MagImageScalingCallback)(HWND hwnd,
59                                                 void* srcdata,
60                                                 MAGIMAGEHEADER srcheader,
61                                                 void* destdata,
62                                                 MAGIMAGEHEADER destheader,
63                                                 RECT unclipped,
64                                                 RECT clipped,
65                                                 HRGN dirty);
66   typedef BOOL(WINAPI* MagInitializeFunc)(void);
67   typedef BOOL(WINAPI* MagUninitializeFunc)(void);
68   typedef BOOL(WINAPI* MagSetWindowSourceFunc)(HWND hwnd, RECT rect);
69   typedef BOOL(WINAPI* MagSetWindowFilterListFunc)(HWND hwnd,
70                                                    DWORD dwFilterMode,
71                                                    int count,
72                                                    HWND* pHWND);
73   typedef BOOL(WINAPI* MagSetImageScalingCallbackFunc)(
74       HWND hwnd,
75       MagImageScalingCallback callback);
76 
77   static BOOL WINAPI OnMagImageScalingCallback(HWND hwnd,
78                                                void* srcdata,
79                                                MAGIMAGEHEADER srcheader,
80                                                void* destdata,
81                                                MAGIMAGEHEADER destheader,
82                                                RECT unclipped,
83                                                RECT clipped,
84                                                HRGN dirty);
85 
86   // Captures the screen within `rect` in the desktop coordinates. Returns true
87   // if succeeded.
88   // It can only capture the primary screen for now. The magnification library
89   // crashes under some screen configurations (e.g. secondary screen on top of
90   // primary screen) if it tries to capture a non-primary screen. The caller
91   // must make sure not calling it on non-primary screens.
92   bool CaptureImage(const DesktopRect& rect);
93 
94   // Helper method for setting up the magnifier control. Returns true if
95   // succeeded.
96   bool InitializeMagnifier();
97 
98   // Called by OnMagImageScalingCallback to output captured data.
99   void OnCaptured(void* data, const MAGIMAGEHEADER& header);
100 
101   // Makes sure the current frame exists and matches `size`.
102   void CreateCurrentFrameIfNecessary(const DesktopSize& size);
103 
104   Callback* callback_ = nullptr;
105   std::unique_ptr<SharedMemoryFactory> shared_memory_factory_;
106   ScreenId current_screen_id_ = kFullDesktopScreenId;
107   std::wstring current_device_key_;
108   HWND excluded_window_ = NULL;
109 
110   // Queue of the frames buffers.
111   ScreenCaptureFrameQueue<SharedDesktopFrame> queue_;
112 
113   ScopedThreadDesktop desktop_;
114 
115   // Used for getting the screen dpi.
116   HDC desktop_dc_ = NULL;
117 
118   HMODULE mag_lib_handle_ = NULL;
119   MagInitializeFunc mag_initialize_func_ = nullptr;
120   MagUninitializeFunc mag_uninitialize_func_ = nullptr;
121   MagSetWindowSourceFunc set_window_source_func_ = nullptr;
122   MagSetWindowFilterListFunc set_window_filter_list_func_ = nullptr;
123   MagSetImageScalingCallbackFunc set_image_scaling_callback_func_ = nullptr;
124 
125   // The hidden window hosting the magnifier control.
126   HWND host_window_ = NULL;
127   // The magnifier control that captures the screen.
128   HWND magnifier_window_ = NULL;
129 
130   // True if the magnifier control has been successfully initialized.
131   bool magnifier_initialized_ = false;
132 
133   // True if the last OnMagImageScalingCallback was called and handled
134   // successfully. Reset at the beginning of each CaptureImage call.
135   bool magnifier_capture_succeeded_ = true;
136 };
137 
138 }  // namespace webrtc
139 
140 #endif  // MODULES_DESKTOP_CAPTURE_WIN_SCREEN_CAPTURER_WIN_MAGNIFIER_H_
141