| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include <fcntl.h> |
| 12 #include <sys/stat.h> |
| 13 #include <semaphore.h> |
| 14 |
| 11 #include <memory> | 15 #include <memory> |
| 12 | 16 |
| 13 #include "webrtc/base/checks.h" | 17 #include "webrtc/base/checks.h" |
| 14 #include "webrtc/modules/desktop_capture/screen_drawer.h" | 18 #include "webrtc/modules/desktop_capture/screen_drawer.h" |
| 15 #include "webrtc/modules/desktop_capture/x11/shared_x_display.h" | 19 #include "webrtc/modules/desktop_capture/x11/shared_x_display.h" |
| 16 #include "webrtc/system_wrappers/include/sleep.h" | 20 #include "webrtc/system_wrappers/include/sleep.h" |
| 17 | 21 |
| 18 namespace webrtc { | 22 namespace webrtc { |
| 19 | 23 |
| 20 namespace { | 24 namespace { |
| 21 | 25 |
| 26 static constexpr char kSemaphoreName[] = |
| 27 "/global-screen-drawer-linux-54fe5552-8047-11e6-a725-3f429a5b4fb4"; |
| 28 |
| 29 // A cross application lock to ensure only one ScreenDrawerLinux can be used at |
| 30 // a certain time. |
| 31 struct ScreenDrawerLock { |
| 32 // Blocks current thread until a global lock is acquired. |
| 33 ScreenDrawerLock(); |
| 34 // Releases the global lock acquired. |
| 35 ~ScreenDrawerLock(); |
| 36 |
| 37 private: |
| 38 sem_t* semaphore_; |
| 39 }; |
| 40 |
| 41 ScreenDrawerLock::ScreenDrawerLock() { |
| 42 semaphore_ = |
| 43 sem_open(kSemaphoreName, O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO, 1); |
| 44 sem_wait(semaphore_); |
| 45 } |
| 46 |
| 47 ScreenDrawerLock::~ScreenDrawerLock() { |
| 48 sem_post(semaphore_); |
| 49 sem_close(semaphore_); |
| 50 // sem_unlink(kSemaphoreName); |
| 51 } |
| 52 |
| 53 std::unique_ptr<ScreenDrawerLock> g_screen_drawer_lock; |
| 54 |
| 22 // A ScreenDrawer implementation for X11. | 55 // A ScreenDrawer implementation for X11. |
| 23 class ScreenDrawerLinux : public ScreenDrawer { | 56 class ScreenDrawerLinux : public ScreenDrawer { |
| 24 public: | 57 public: |
| 25 ScreenDrawerLinux(); | 58 ScreenDrawerLinux(); |
| 26 ~ScreenDrawerLinux() override; | 59 ~ScreenDrawerLinux() override; |
| 27 | 60 |
| 28 // ScreenDrawer interface. | 61 // ScreenDrawer interface. |
| 29 DesktopRect DrawableRegion() override; | 62 DesktopRect DrawableRegion() override; |
| 30 void DrawRectangle(DesktopRect rect, RgbaColor color) override; | 63 void DrawRectangle(DesktopRect rect, RgbaColor color) override; |
| 31 void Clear() override; | 64 void Clear() override; |
| 32 void WaitForPendingDraws() override; | 65 void WaitForPendingDraws() override; |
| 66 bool MayDrawIncompleteShapes() override; |
| 33 | 67 |
| 34 private: | 68 private: |
| 69 // Bring the window to the front, this can help to avoid the impact from other |
| 70 // windows or shadow effect. |
| 71 void BringToFront(); |
| 72 |
| 35 rtc::scoped_refptr<SharedXDisplay> display_; | 73 rtc::scoped_refptr<SharedXDisplay> display_; |
| 36 int screen_num_; | 74 int screen_num_; |
| 37 DesktopRect rect_; | 75 DesktopRect rect_; |
| 38 Window window_; | 76 Window window_; |
| 39 GC context_; | 77 GC context_; |
| 40 Colormap colormap_; | 78 Colormap colormap_; |
| 41 }; | 79 }; |
| 42 | 80 |
| 43 ScreenDrawerLinux::ScreenDrawerLinux() { | 81 ScreenDrawerLinux::ScreenDrawerLinux() { |
| 44 display_ = SharedXDisplay::CreateDefault(); | 82 display_ = SharedXDisplay::CreateDefault(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 73 RTC_DCHECK(false) << "Failed to get window position."; | 111 RTC_DCHECK(false) << "Failed to get window position."; |
| 74 } | 112 } |
| 75 // Some window manager does not allow a window to cover two or more monitors. | 113 // Some window manager does not allow a window to cover two or more monitors. |
| 76 // So if the window is on the first monitor of a two-monitor system, the | 114 // So if the window is on the first monitor of a two-monitor system, the |
| 77 // second half won't be able to show up without changing configurations of WM, | 115 // second half won't be able to show up without changing configurations of WM, |
| 78 // and its DrawableRegion() is not accurate. | 116 // and its DrawableRegion() is not accurate. |
| 79 rect_ = DesktopRect::MakeLTRB(x, y, root_attributes.width, | 117 rect_ = DesktopRect::MakeLTRB(x, y, root_attributes.width, |
| 80 root_attributes.height); | 118 root_attributes.height); |
| 81 context_ = DefaultGC(display_->display(), screen_num_); | 119 context_ = DefaultGC(display_->display(), screen_num_); |
| 82 colormap_ = DefaultColormap(display_->display(), screen_num_); | 120 colormap_ = DefaultColormap(display_->display(), screen_num_); |
| 121 BringToFront(); |
| 83 // Wait for window animations. | 122 // Wait for window animations. |
| 84 SleepMs(200); | 123 SleepMs(200); |
| 85 } | 124 } |
| 86 | 125 |
| 87 ScreenDrawerLinux::~ScreenDrawerLinux() { | 126 ScreenDrawerLinux::~ScreenDrawerLinux() { |
| 88 XUnmapWindow(display_->display(), window_); | 127 XUnmapWindow(display_->display(), window_); |
| 89 XDestroyWindow(display_->display(), window_); | 128 XDestroyWindow(display_->display(), window_); |
| 129 g_screen_drawer_lock.reset(); |
| 90 } | 130 } |
| 91 | 131 |
| 92 DesktopRect ScreenDrawerLinux::DrawableRegion() { | 132 DesktopRect ScreenDrawerLinux::DrawableRegion() { |
| 93 return rect_; | 133 return rect_; |
| 94 } | 134 } |
| 95 | 135 |
| 96 void ScreenDrawerLinux::DrawRectangle(DesktopRect rect, RgbaColor color) { | 136 void ScreenDrawerLinux::DrawRectangle(DesktopRect rect, RgbaColor color) { |
| 97 rect.Translate(-rect_.left(), -rect_.top()); | 137 rect.Translate(-rect_.left(), -rect_.top()); |
| 98 XColor xcolor; | 138 XColor xcolor; |
| 99 // X11 does not support Alpha. | 139 // X11 does not support Alpha. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 111 XFlush(display_->display()); | 151 XFlush(display_->display()); |
| 112 } | 152 } |
| 113 | 153 |
| 114 void ScreenDrawerLinux::Clear() { | 154 void ScreenDrawerLinux::Clear() { |
| 115 DrawRectangle(rect_, RgbaColor(0, 0, 0)); | 155 DrawRectangle(rect_, RgbaColor(0, 0, 0)); |
| 116 } | 156 } |
| 117 | 157 |
| 118 // TODO(zijiehe): Find the right signal from X11 to indicate the finish of all | 158 // TODO(zijiehe): Find the right signal from X11 to indicate the finish of all |
| 119 // pending paintings. | 159 // pending paintings. |
| 120 void ScreenDrawerLinux::WaitForPendingDraws() { | 160 void ScreenDrawerLinux::WaitForPendingDraws() { |
| 161 BringToFront(); |
| 121 SleepMs(50); | 162 SleepMs(50); |
| 122 } | 163 } |
| 123 | 164 |
| 165 bool ScreenDrawerLinux::MayDrawIncompleteShapes() { |
| 166 return true; |
| 167 } |
| 168 |
| 169 void ScreenDrawerLinux::BringToFront() { |
| 170 XRaiseWindow(display_->display(), window_); |
| 171 } |
| 172 |
| 124 } // namespace | 173 } // namespace |
| 125 | 174 |
| 126 // static | 175 // static |
| 127 std::unique_ptr<ScreenDrawer> ScreenDrawer::Create() { | 176 std::unique_ptr<ScreenDrawer> ScreenDrawer::Create() { |
| 128 if (SharedXDisplay::CreateDefault().get()) { | 177 if (SharedXDisplay::CreateDefault().get()) { |
| 178 g_screen_drawer_lock.reset(new ScreenDrawerLock()); |
| 129 return std::unique_ptr<ScreenDrawer>(new ScreenDrawerLinux()); | 179 return std::unique_ptr<ScreenDrawer>(new ScreenDrawerLinux()); |
| 130 } | 180 } |
| 131 return nullptr; | 181 return nullptr; |
| 132 } | 182 } |
| 133 | 183 |
| 134 } // namespace webrtc | 184 } // namespace webrtc |
| OLD | NEW |