| 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 #include <string.h> |
| 15 |
| 11 #include <memory> | 16 #include <memory> |
| 12 | 17 |
| 13 #include "webrtc/base/checks.h" | 18 #include "webrtc/base/checks.h" |
| 14 #include "webrtc/modules/desktop_capture/screen_drawer.h" | 19 #include "webrtc/modules/desktop_capture/screen_drawer.h" |
| 15 #include "webrtc/modules/desktop_capture/x11/shared_x_display.h" | 20 #include "webrtc/modules/desktop_capture/x11/shared_x_display.h" |
| 16 #include "webrtc/system_wrappers/include/sleep.h" | 21 #include "webrtc/system_wrappers/include/sleep.h" |
| 17 | 22 |
| 18 namespace webrtc { | 23 namespace webrtc { |
| 19 | 24 |
| 20 namespace { | 25 namespace { |
| 21 | 26 |
| 27 static constexpr char kSemaphoreName[] = |
| 28 "/global-screen-drawer-linux-54fe5552-8047-11e6-a725-3f429a5b4fb4"; |
| 29 |
| 30 class ScreenDrawerLockLinux : public ScreenDrawerLock { |
| 31 public: |
| 32 ScreenDrawerLockLinux(); |
| 33 ~ScreenDrawerLockLinux(); |
| 34 |
| 35 private: |
| 36 sem_t* semaphore_; |
| 37 }; |
| 38 |
| 39 ScreenDrawerLockLinux::ScreenDrawerLockLinux() { |
| 40 semaphore_ = |
| 41 sem_open(kSemaphoreName, O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO, 1); |
| 42 sem_wait(semaphore_); |
| 43 } |
| 44 |
| 45 ScreenDrawerLockLinux::~ScreenDrawerLockLinux() { |
| 46 sem_post(semaphore_); |
| 47 sem_close(semaphore_); |
| 48 // sem_unlink(kSemaphoreName); |
| 49 } |
| 50 |
| 22 // A ScreenDrawer implementation for X11. | 51 // A ScreenDrawer implementation for X11. |
| 23 class ScreenDrawerLinux : public ScreenDrawer { | 52 class ScreenDrawerLinux : public ScreenDrawer { |
| 24 public: | 53 public: |
| 25 ScreenDrawerLinux(); | 54 ScreenDrawerLinux(); |
| 26 ~ScreenDrawerLinux() override; | 55 ~ScreenDrawerLinux() override; |
| 27 | 56 |
| 28 // ScreenDrawer interface. | 57 // ScreenDrawer interface. |
| 29 DesktopRect DrawableRegion() override; | 58 DesktopRect DrawableRegion() override; |
| 30 void DrawRectangle(DesktopRect rect, RgbaColor color) override; | 59 void DrawRectangle(DesktopRect rect, RgbaColor color) override; |
| 31 void Clear() override; | 60 void Clear() override; |
| 32 void WaitForPendingDraws() override; | 61 void WaitForPendingDraws() override; |
| 62 bool MayDrawIncompleteShapes() override; |
| 33 | 63 |
| 34 private: | 64 private: |
| 65 // Bring the window to the front, this can help to avoid the impact from other |
| 66 // windows or shadow effect. |
| 67 void BringToFront(); |
| 68 |
| 35 rtc::scoped_refptr<SharedXDisplay> display_; | 69 rtc::scoped_refptr<SharedXDisplay> display_; |
| 36 int screen_num_; | 70 int screen_num_; |
| 37 DesktopRect rect_; | 71 DesktopRect rect_; |
| 38 Window window_; | 72 Window window_; |
| 39 GC context_; | 73 GC context_; |
| 40 Colormap colormap_; | 74 Colormap colormap_; |
| 41 }; | 75 }; |
| 42 | 76 |
| 43 ScreenDrawerLinux::ScreenDrawerLinux() { | 77 ScreenDrawerLinux::ScreenDrawerLinux() { |
| 44 display_ = SharedXDisplay::CreateDefault(); | 78 display_ = SharedXDisplay::CreateDefault(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 73 RTC_DCHECK(false) << "Failed to get window position."; | 107 RTC_DCHECK(false) << "Failed to get window position."; |
| 74 } | 108 } |
| 75 // Some window manager does not allow a window to cover two or more monitors. | 109 // 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 | 110 // 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, | 111 // second half won't be able to show up without changing configurations of WM, |
| 78 // and its DrawableRegion() is not accurate. | 112 // and its DrawableRegion() is not accurate. |
| 79 rect_ = DesktopRect::MakeLTRB(x, y, root_attributes.width, | 113 rect_ = DesktopRect::MakeLTRB(x, y, root_attributes.width, |
| 80 root_attributes.height); | 114 root_attributes.height); |
| 81 context_ = DefaultGC(display_->display(), screen_num_); | 115 context_ = DefaultGC(display_->display(), screen_num_); |
| 82 colormap_ = DefaultColormap(display_->display(), screen_num_); | 116 colormap_ = DefaultColormap(display_->display(), screen_num_); |
| 117 BringToFront(); |
| 83 // Wait for window animations. | 118 // Wait for window animations. |
| 84 SleepMs(200); | 119 SleepMs(200); |
| 85 } | 120 } |
| 86 | 121 |
| 87 ScreenDrawerLinux::~ScreenDrawerLinux() { | 122 ScreenDrawerLinux::~ScreenDrawerLinux() { |
| 88 XUnmapWindow(display_->display(), window_); | 123 XUnmapWindow(display_->display(), window_); |
| 89 XDestroyWindow(display_->display(), window_); | 124 XDestroyWindow(display_->display(), window_); |
| 90 } | 125 } |
| 91 | 126 |
| 92 DesktopRect ScreenDrawerLinux::DrawableRegion() { | 127 DesktopRect ScreenDrawerLinux::DrawableRegion() { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 114 void ScreenDrawerLinux::Clear() { | 149 void ScreenDrawerLinux::Clear() { |
| 115 DrawRectangle(rect_, RgbaColor(0, 0, 0)); | 150 DrawRectangle(rect_, RgbaColor(0, 0, 0)); |
| 116 } | 151 } |
| 117 | 152 |
| 118 // TODO(zijiehe): Find the right signal from X11 to indicate the finish of all | 153 // TODO(zijiehe): Find the right signal from X11 to indicate the finish of all |
| 119 // pending paintings. | 154 // pending paintings. |
| 120 void ScreenDrawerLinux::WaitForPendingDraws() { | 155 void ScreenDrawerLinux::WaitForPendingDraws() { |
| 121 SleepMs(50); | 156 SleepMs(50); |
| 122 } | 157 } |
| 123 | 158 |
| 159 bool ScreenDrawerLinux::MayDrawIncompleteShapes() { |
| 160 return true; |
| 161 } |
| 162 |
| 163 void ScreenDrawerLinux::BringToFront() { |
| 164 Atom state_above = XInternAtom(display_->display(), "_NET_WM_STATE_ABOVE", 1); |
| 165 Atom window_state = XInternAtom(display_->display(), "_NET_WM_STATE", 1); |
| 166 if (state_above == None || window_state == None) { |
| 167 // Fallback to use XRaiseWindow, it's not reliable if two windows are both |
| 168 // raise itself to the top. |
| 169 XRaiseWindow(display_->display(), window_); |
| 170 return; |
| 171 } |
| 172 |
| 173 XEvent event; |
| 174 memset(&event, 0, sizeof(event)); |
| 175 event.type = ClientMessage; |
| 176 event.xclient.window = window_; |
| 177 event.xclient.message_type = window_state; |
| 178 event.xclient.format = 32; |
| 179 event.xclient.data.l[0] = 1; // _NET_WM_STATE_ADD |
| 180 event.xclient.data.l[1] = state_above; |
| 181 XSendEvent(display_->display(), RootWindow(display_->display(), screen_num_), |
| 182 False, SubstructureRedirectMask | SubstructureNotifyMask, &event); |
| 183 } |
| 184 |
| 124 } // namespace | 185 } // namespace |
| 125 | 186 |
| 126 // static | 187 // static |
| 188 std::unique_ptr<ScreenDrawerLock> ScreenDrawerLock::Create() { |
| 189 return std::unique_ptr<ScreenDrawerLock>(new ScreenDrawerLockLinux()); |
| 190 } |
| 191 |
| 192 // static |
| 127 std::unique_ptr<ScreenDrawer> ScreenDrawer::Create() { | 193 std::unique_ptr<ScreenDrawer> ScreenDrawer::Create() { |
| 128 if (SharedXDisplay::CreateDefault().get()) { | 194 if (SharedXDisplay::CreateDefault().get()) { |
| 129 return std::unique_ptr<ScreenDrawer>(new ScreenDrawerLinux()); | 195 return std::unique_ptr<ScreenDrawer>(new ScreenDrawerLinux()); |
| 130 } | 196 } |
| 131 return nullptr; | 197 return nullptr; |
| 132 } | 198 } |
| 133 | 199 |
| 134 } // namespace webrtc | 200 } // namespace webrtc |
| OLD | NEW |