| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 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 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 | 81 |
| 82 RTC_DISALLOW_COPY_AND_ASSIGN(XWindowProperty); | 82 RTC_DISALLOW_COPY_AND_ASSIGN(XWindowProperty); |
| 83 }; | 83 }; |
| 84 | 84 |
| 85 class WindowCapturerLinux : public WindowCapturer, | 85 class WindowCapturerLinux : public WindowCapturer, |
| 86 public SharedXDisplay::XEventHandler { | 86 public SharedXDisplay::XEventHandler { |
| 87 public: | 87 public: |
| 88 WindowCapturerLinux(const DesktopCaptureOptions& options); | 88 WindowCapturerLinux(const DesktopCaptureOptions& options); |
| 89 ~WindowCapturerLinux() override; | 89 ~WindowCapturerLinux() override; |
| 90 | 90 |
| 91 // WindowCapturer interface. | |
| 92 bool GetWindowList(WindowList* windows) override; | |
| 93 bool SelectWindow(WindowId id) override; | |
| 94 bool BringSelectedWindowToFront() override; | |
| 95 | |
| 96 // DesktopCapturer interface. | 91 // DesktopCapturer interface. |
| 97 void Start(Callback* callback) override; | 92 void Start(Callback* callback) override; |
| 98 void CaptureFrame() override; | 93 void CaptureFrame() override; |
| 94 bool GetSourceList(SourceList* sources) override; |
| 95 bool SelectSource(SourceId id) override; |
| 96 bool FocusOnSelectedSource() override; |
| 99 | 97 |
| 100 // SharedXDisplay::XEventHandler interface. | 98 // SharedXDisplay::XEventHandler interface. |
| 101 bool HandleXEvent(const XEvent& event) override; | 99 bool HandleXEvent(const XEvent& event) override; |
| 102 | 100 |
| 103 private: | 101 private: |
| 104 Display* display() { return x_display_->display(); } | 102 Display* display() { return x_display_->display(); } |
| 105 | 103 |
| 106 // Iterates through |window| hierarchy to find first visible window, i.e. one | 104 // Iterates through |window| hierarchy to find first visible window, i.e. one |
| 107 // that has WM_STATE property set to NormalState. | 105 // that has WM_STATE property set to NormalState. |
| 108 // See http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.3.1 . | 106 // See http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.3.1 . |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 LOG(LS_INFO) << "Xcomposite extension not available or too old."; | 145 LOG(LS_INFO) << "Xcomposite extension not available or too old."; |
| 148 } | 146 } |
| 149 | 147 |
| 150 x_display_->AddEventHandler(ConfigureNotify, this); | 148 x_display_->AddEventHandler(ConfigureNotify, this); |
| 151 } | 149 } |
| 152 | 150 |
| 153 WindowCapturerLinux::~WindowCapturerLinux() { | 151 WindowCapturerLinux::~WindowCapturerLinux() { |
| 154 x_display_->RemoveEventHandler(ConfigureNotify, this); | 152 x_display_->RemoveEventHandler(ConfigureNotify, this); |
| 155 } | 153 } |
| 156 | 154 |
| 157 bool WindowCapturerLinux::GetWindowList(WindowList* windows) { | 155 bool WindowCapturerLinux::GetSourceList(SourceList* sources) { |
| 158 WindowList result; | 156 SourceList result; |
| 159 | 157 |
| 160 XErrorTrap error_trap(display()); | 158 XErrorTrap error_trap(display()); |
| 161 | 159 |
| 162 int num_screens = XScreenCount(display()); | 160 int num_screens = XScreenCount(display()); |
| 163 for (int screen = 0; screen < num_screens; ++screen) { | 161 for (int screen = 0; screen < num_screens; ++screen) { |
| 164 ::Window root_window = XRootWindow(display(), screen); | 162 ::Window root_window = XRootWindow(display(), screen); |
| 165 ::Window parent; | 163 ::Window parent; |
| 166 ::Window *children; | 164 ::Window *children; |
| 167 unsigned int num_children; | 165 unsigned int num_children; |
| 168 int status = XQueryTree(display(), root_window, &root_window, &parent, | 166 int status = XQueryTree(display(), root_window, &root_window, &parent, |
| 169 &children, &num_children); | 167 &children, &num_children); |
| 170 if (status == 0) { | 168 if (status == 0) { |
| 171 LOG(LS_ERROR) << "Failed to query for child windows for screen " | 169 LOG(LS_ERROR) << "Failed to query for child windows for screen " |
| 172 << screen; | 170 << screen; |
| 173 continue; | 171 continue; |
| 174 } | 172 } |
| 175 | 173 |
| 176 for (unsigned int i = 0; i < num_children; ++i) { | 174 for (unsigned int i = 0; i < num_children; ++i) { |
| 177 // Iterate in reverse order to return windows from front to back. | 175 // Iterate in reverse order to return windows from front to back. |
| 178 ::Window app_window = | 176 ::Window app_window = |
| 179 GetApplicationWindow(children[num_children - 1 - i]); | 177 GetApplicationWindow(children[num_children - 1 - i]); |
| 180 if (app_window && !IsDesktopElement(app_window)) { | 178 if (app_window && !IsDesktopElement(app_window)) { |
| 181 Window w; | 179 Source w; |
| 182 w.id = app_window; | 180 w.id = app_window; |
| 183 if (GetWindowTitle(app_window, &w.title)) | 181 if (GetWindowTitle(app_window, &w.title)) |
| 184 result.push_back(w); | 182 result.push_back(w); |
| 185 } | 183 } |
| 186 } | 184 } |
| 187 | 185 |
| 188 if (children) | 186 if (children) |
| 189 XFree(children); | 187 XFree(children); |
| 190 } | 188 } |
| 191 | 189 |
| 192 windows->swap(result); | 190 sources->swap(result); |
| 193 | 191 |
| 194 return true; | 192 return true; |
| 195 } | 193 } |
| 196 | 194 |
| 197 bool WindowCapturerLinux::SelectWindow(WindowId id) { | 195 bool WindowCapturerLinux::SelectSource(SourceId id) { |
| 198 if (!x_server_pixel_buffer_.Init(display(), id)) | 196 if (!x_server_pixel_buffer_.Init(display(), id)) |
| 199 return false; | 197 return false; |
| 200 | 198 |
| 201 // Tell the X server to send us window resizing events. | 199 // Tell the X server to send us window resizing events. |
| 202 XSelectInput(display(), id, StructureNotifyMask); | 200 XSelectInput(display(), id, StructureNotifyMask); |
| 203 | 201 |
| 204 selected_window_ = id; | 202 selected_window_ = id; |
| 205 | 203 |
| 206 // In addition to needing X11 server-side support for Xcomposite, it actually | 204 // In addition to needing X11 server-side support for Xcomposite, it actually |
| 207 // needs to be turned on for the window. If the user has modern | 205 // needs to be turned on for the window. If the user has modern |
| 208 // hardware/drivers but isn't using a compositing window manager, that won't | 206 // hardware/drivers but isn't using a compositing window manager, that won't |
| 209 // be the case. Here we automatically turn it on. | 207 // be the case. Here we automatically turn it on. |
| 210 | 208 |
| 211 // Redirect drawing to an offscreen buffer (ie, turn on compositing). X11 | 209 // Redirect drawing to an offscreen buffer (ie, turn on compositing). X11 |
| 212 // remembers who has requested this and will turn it off for us when we exit. | 210 // remembers who has requested this and will turn it off for us when we exit. |
| 213 XCompositeRedirectWindow(display(), id, CompositeRedirectAutomatic); | 211 XCompositeRedirectWindow(display(), id, CompositeRedirectAutomatic); |
| 214 | 212 |
| 215 return true; | 213 return true; |
| 216 } | 214 } |
| 217 | 215 |
| 218 bool WindowCapturerLinux::BringSelectedWindowToFront() { | 216 bool WindowCapturerLinux::FocusOnSelectedSource() { |
| 219 if (!selected_window_) | 217 if (!selected_window_) |
| 220 return false; | 218 return false; |
| 221 | 219 |
| 222 unsigned int num_children; | 220 unsigned int num_children; |
| 223 ::Window* children; | 221 ::Window* children; |
| 224 ::Window parent; | 222 ::Window parent; |
| 225 ::Window root; | 223 ::Window root; |
| 226 // Find the root window to pass event to. | 224 // Find the root window to pass event to. |
| 227 int status = XQueryTree( | 225 int status = XQueryTree( |
| 228 display(), selected_window_, &root, &parent, &children, &num_children); | 226 display(), selected_window_, &root, &parent, &children, &num_children); |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 | 430 |
| 433 // static | 431 // static |
| 434 std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawWindowCapturer( | 432 std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawWindowCapturer( |
| 435 const DesktopCaptureOptions& options) { | 433 const DesktopCaptureOptions& options) { |
| 436 if (!options.x_display()) | 434 if (!options.x_display()) |
| 437 return nullptr; | 435 return nullptr; |
| 438 return std::unique_ptr<DesktopCapturer>(new WindowCapturerLinux(options)); | 436 return std::unique_ptr<DesktopCapturer>(new WindowCapturerLinux(options)); |
| 439 } | 437 } |
| 440 | 438 |
| 441 } // namespace webrtc | 439 } // namespace webrtc |
| OLD | NEW |