• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "rtc_base/constructor_magic.h"
26 
27 namespace webrtc {
28 
29 class DesktopFrame;
30 class DesktopRect;
31 
32 // Captures the screen using the Magnification API to support window exclusion.
33 // Each capturer must run on a dedicated thread because it uses thread local
34 // storage for redirecting the library callback. Also the thread must have a UI
35 // message loop to handle the window messages for the magnifier window.
36 //
37 // This class does not detect DesktopFrame::updated_region(), the field is
38 // always set to the entire frame rectangle. ScreenCapturerDifferWrapper should
39 // be used if that functionality is necessary.
40 class ScreenCapturerWinMagnifier : public DesktopCapturer {
41  public:
42   ScreenCapturerWinMagnifier();
43   ~ScreenCapturerWinMagnifier() override;
44 
45   // Overridden from ScreenCapturer:
46   void Start(Callback* callback) override;
47   void SetSharedMemoryFactory(
48       std::unique_ptr<SharedMemoryFactory> shared_memory_factory) override;
49   void CaptureFrame() override;
50   bool GetSourceList(SourceList* screens) override;
51   bool SelectSource(SourceId id) override;
52   void SetExcludedWindow(WindowId window) override;
53 
54  private:
55   typedef BOOL(WINAPI* MagImageScalingCallback)(HWND hwnd,
56                                                 void* srcdata,
57                                                 MAGIMAGEHEADER srcheader,
58                                                 void* destdata,
59                                                 MAGIMAGEHEADER destheader,
60                                                 RECT unclipped,
61                                                 RECT clipped,
62                                                 HRGN dirty);
63   typedef BOOL(WINAPI* MagInitializeFunc)(void);
64   typedef BOOL(WINAPI* MagUninitializeFunc)(void);
65   typedef BOOL(WINAPI* MagSetWindowSourceFunc)(HWND hwnd, RECT rect);
66   typedef BOOL(WINAPI* MagSetWindowFilterListFunc)(HWND hwnd,
67                                                    DWORD dwFilterMode,
68                                                    int count,
69                                                    HWND* pHWND);
70   typedef BOOL(WINAPI* MagSetImageScalingCallbackFunc)(
71       HWND hwnd,
72       MagImageScalingCallback callback);
73 
74   static BOOL WINAPI OnMagImageScalingCallback(HWND hwnd,
75                                                void* srcdata,
76                                                MAGIMAGEHEADER srcheader,
77                                                void* destdata,
78                                                MAGIMAGEHEADER destheader,
79                                                RECT unclipped,
80                                                RECT clipped,
81                                                HRGN dirty);
82 
83   // Captures the screen within |rect| in the desktop coordinates. Returns true
84   // if succeeded.
85   // It can only capture the primary screen for now. The magnification library
86   // crashes under some screen configurations (e.g. secondary screen on top of
87   // primary screen) if it tries to capture a non-primary screen. The caller
88   // must make sure not calling it on non-primary screens.
89   bool CaptureImage(const DesktopRect& rect);
90 
91   // Helper method for setting up the magnifier control. Returns true if
92   // succeeded.
93   bool InitializeMagnifier();
94 
95   // Called by OnMagImageScalingCallback to output captured data.
96   void OnCaptured(void* data, const MAGIMAGEHEADER& header);
97 
98   // Makes sure the current frame exists and matches |size|.
99   void CreateCurrentFrameIfNecessary(const DesktopSize& size);
100 
101   Callback* callback_ = nullptr;
102   std::unique_ptr<SharedMemoryFactory> shared_memory_factory_;
103   ScreenId current_screen_id_ = kFullDesktopScreenId;
104   std::wstring current_device_key_;
105   HWND excluded_window_ = NULL;
106 
107   // Queue of the frames buffers.
108   ScreenCaptureFrameQueue<SharedDesktopFrame> queue_;
109 
110   ScopedThreadDesktop desktop_;
111 
112   // Used for getting the screen dpi.
113   HDC desktop_dc_ = NULL;
114 
115   HMODULE mag_lib_handle_ = NULL;
116   MagInitializeFunc mag_initialize_func_ = nullptr;
117   MagUninitializeFunc mag_uninitialize_func_ = nullptr;
118   MagSetWindowSourceFunc set_window_source_func_ = nullptr;
119   MagSetWindowFilterListFunc set_window_filter_list_func_ = nullptr;
120   MagSetImageScalingCallbackFunc set_image_scaling_callback_func_ = nullptr;
121 
122   // The hidden window hosting the magnifier control.
123   HWND host_window_ = NULL;
124   // The magnifier control that captures the screen.
125   HWND magnifier_window_ = NULL;
126 
127   // True if the magnifier control has been successfully initialized.
128   bool magnifier_initialized_ = false;
129 
130   // True if the last OnMagImageScalingCallback was called and handled
131   // successfully. Reset at the beginning of each CaptureImage call.
132   bool magnifier_capture_succeeded_ = true;
133 
134   RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerWinMagnifier);
135 };
136 
137 }  // namespace webrtc
138 
139 #endif  // MODULES_DESKTOP_CAPTURE_WIN_SCREEN_CAPTURER_WIN_MAGNIFIER_H_
140