screen_capturer_x11.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * Copyright 2018 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. #ifndef MODULES_DESKTOP_CAPTURE_LINUX_SCREEN_CAPTURER_X11_H_
  11. #define MODULES_DESKTOP_CAPTURE_LINUX_SCREEN_CAPTURER_X11_H_
  12. #include <X11/X.h>
  13. #include <X11/Xlib.h>
  14. #include <X11/extensions/Xdamage.h>
  15. #include <X11/extensions/Xfixes.h>
  16. #include <X11/extensions/Xrandr.h>
  17. #include <memory>
  18. #include "modules/desktop_capture/desktop_capture_options.h"
  19. #include "modules/desktop_capture/desktop_capturer.h"
  20. #include "modules/desktop_capture/desktop_frame.h"
  21. #include "modules/desktop_capture/desktop_region.h"
  22. #include "modules/desktop_capture/linux/shared_x_display.h"
  23. #include "modules/desktop_capture/linux/x_atom_cache.h"
  24. #include "modules/desktop_capture/linux/x_server_pixel_buffer.h"
  25. #include "modules/desktop_capture/screen_capture_frame_queue.h"
  26. #include "modules/desktop_capture/screen_capturer_helper.h"
  27. #include "modules/desktop_capture/shared_desktop_frame.h"
  28. #include "rtc_base/constructor_magic.h"
  29. namespace webrtc {
  30. // A class to perform video frame capturing for Linux on X11.
  31. //
  32. // If XDamage is used, this class sets DesktopFrame::updated_region() according
  33. // to the areas reported by XDamage. Otherwise this class does not detect
  34. // DesktopFrame::updated_region(), the field is always set to the entire frame
  35. // rectangle. ScreenCapturerDifferWrapper should be used if that functionality
  36. // is necessary.
  37. class ScreenCapturerX11 : public DesktopCapturer,
  38. public SharedXDisplay::XEventHandler {
  39. public:
  40. ScreenCapturerX11();
  41. ~ScreenCapturerX11() override;
  42. static std::unique_ptr<DesktopCapturer> CreateRawScreenCapturer(
  43. const DesktopCaptureOptions& options);
  44. // TODO(ajwong): Do we really want this to be synchronous?
  45. bool Init(const DesktopCaptureOptions& options);
  46. // DesktopCapturer interface.
  47. void Start(Callback* delegate) override;
  48. void CaptureFrame() override;
  49. bool GetSourceList(SourceList* sources) override;
  50. bool SelectSource(SourceId id) override;
  51. private:
  52. Display* display() { return options_.x_display()->display(); }
  53. // SharedXDisplay::XEventHandler interface.
  54. bool HandleXEvent(const XEvent& event) override;
  55. void InitXDamage();
  56. void InitXrandr();
  57. void UpdateMonitors();
  58. // Capture screen pixels to the current buffer in the queue. In the DAMAGE
  59. // case, the ScreenCapturerHelper already holds the list of invalid rectangles
  60. // from HandleXEvent(). In the non-DAMAGE case, this captures the
  61. // whole screen, then calculates some invalid rectangles that include any
  62. // differences between this and the previous capture.
  63. std::unique_ptr<DesktopFrame> CaptureScreen();
  64. // Called when the screen configuration is changed.
  65. void ScreenConfigurationChanged();
  66. // Synchronize the current buffer with |last_buffer_|, by copying pixels from
  67. // the area of |last_invalid_rects|.
  68. // Note this only works on the assumption that kNumBuffers == 2, as
  69. // |last_invalid_rects| holds the differences from the previous buffer and
  70. // the one prior to that (which will then be the current buffer).
  71. void SynchronizeFrame();
  72. void DeinitXlib();
  73. DesktopCaptureOptions options_;
  74. Callback* callback_ = nullptr;
  75. // X11 graphics context.
  76. GC gc_ = nullptr;
  77. Window root_window_ = BadValue;
  78. // XRandR 1.5 monitors.
  79. bool use_randr_ = false;
  80. int randr_event_base_ = 0;
  81. XRRMonitorInfo* monitors_ = nullptr;
  82. int num_monitors_ = 0;
  83. DesktopRect selected_monitor_rect_;
  84. // selected_monitor_name_ will be changed to kFullDesktopScreenId
  85. // by a call to SelectSource() at the end of Init() because
  86. // selected_monitor_rect_ should be updated as well.
  87. // Setting it to kFullDesktopScreenId here might be misleading.
  88. Atom selected_monitor_name_ = 0;
  89. typedef XRRMonitorInfo* (*get_monitors_func)(Display*, Window, Bool, int*);
  90. typedef void (*free_monitors_func)(XRRMonitorInfo*);
  91. get_monitors_func get_monitors_ = nullptr;
  92. free_monitors_func free_monitors_ = nullptr;
  93. // XFixes.
  94. bool has_xfixes_ = false;
  95. int xfixes_event_base_ = -1;
  96. int xfixes_error_base_ = -1;
  97. // XDamage information.
  98. bool use_damage_ = false;
  99. Damage damage_handle_ = 0;
  100. int damage_event_base_ = -1;
  101. int damage_error_base_ = -1;
  102. XserverRegion damage_region_ = 0;
  103. // Access to the X Server's pixel buffer.
  104. XServerPixelBuffer x_server_pixel_buffer_;
  105. // A thread-safe list of invalid rectangles, and the size of the most
  106. // recently captured screen.
  107. ScreenCapturerHelper helper_;
  108. // Queue of the frames buffers.
  109. ScreenCaptureFrameQueue<SharedDesktopFrame> queue_;
  110. // Invalid region from the previous capture. This is used to synchronize the
  111. // current with the last buffer used.
  112. DesktopRegion last_invalid_region_;
  113. std::unique_ptr<XAtomCache> atom_cache_;
  114. RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerX11);
  115. };
  116. } // namespace webrtc
  117. #endif // MODULES_DESKTOP_CAPTURE_LINUX_SCREEN_CAPTURER_X11_H_