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 |