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