tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

screen_capturer_win_magnifier.h (6114B)


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