Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(393)

Side by Side Diff: webrtc/modules/desktop_capture/window_capturer_x11.cc

Issue 1988783003: Use std::unique_ptr<> to pass frame ownership in DesktopCapturer impls. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/modules/desktop_capture/window_capturer_win.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 18 matching lines...) Expand all
29 #include "webrtc/system_wrappers/include/logging.h" 29 #include "webrtc/system_wrappers/include/logging.h"
30 30
31 namespace webrtc { 31 namespace webrtc {
32 32
33 namespace { 33 namespace {
34 34
35 // Convenience wrapper for XGetWindowProperty() results. 35 // Convenience wrapper for XGetWindowProperty() results.
36 template <class PropertyType> 36 template <class PropertyType>
37 class XWindowProperty { 37 class XWindowProperty {
38 public: 38 public:
39 XWindowProperty(Display* display, Window window, Atom property) 39 XWindowProperty(Display* display, Window window, Atom property) {
40 : is_valid_(false),
41 size_(0),
42 data_(NULL) {
43 const int kBitsPerByte = 8; 40 const int kBitsPerByte = 8;
44 Atom actual_type; 41 Atom actual_type;
45 int actual_format; 42 int actual_format;
46 unsigned long bytes_after; // NOLINT: type required by XGetWindowProperty 43 unsigned long bytes_after; // NOLINT: type required by XGetWindowProperty
47 int status = XGetWindowProperty(display, window, property, 0L, ~0L, False, 44 int status = XGetWindowProperty(display, window, property, 0L, ~0L, False,
48 AnyPropertyType, &actual_type, 45 AnyPropertyType, &actual_type,
49 &actual_format, &size_, 46 &actual_format, &size_,
50 &bytes_after, &data_); 47 &bytes_after, &data_);
51 if (status != Success) { 48 if (status != Success) {
52 data_ = NULL; 49 data_ = nullptr;
53 return; 50 return;
54 } 51 }
55 if (sizeof(PropertyType) * kBitsPerByte != actual_format) { 52 if (sizeof(PropertyType) * kBitsPerByte != actual_format) {
56 size_ = 0; 53 size_ = 0;
57 return; 54 return;
58 } 55 }
59 56
60 is_valid_ = true; 57 is_valid_ = true;
61 } 58 }
62 59
63 ~XWindowProperty() { 60 ~XWindowProperty() {
64 if (data_) 61 if (data_)
65 XFree(data_); 62 XFree(data_);
66 } 63 }
67 64
68 // True if we got properly value successfully. 65 // True if we got properly value successfully.
69 bool is_valid() const { return is_valid_; } 66 bool is_valid() const { return is_valid_; }
70 67
71 // Size and value of the property. 68 // Size and value of the property.
72 size_t size() const { return size_; } 69 size_t size() const { return size_; }
73 const PropertyType* data() const { 70 const PropertyType* data() const {
74 return reinterpret_cast<PropertyType*>(data_); 71 return reinterpret_cast<PropertyType*>(data_);
75 } 72 }
76 PropertyType* data() { 73 PropertyType* data() {
77 return reinterpret_cast<PropertyType*>(data_); 74 return reinterpret_cast<PropertyType*>(data_);
78 } 75 }
79 76
80 private: 77 private:
81 bool is_valid_; 78 bool is_valid_ = false;
82 unsigned long size_; // NOLINT: type required by XGetWindowProperty 79 unsigned long size_ = 0; // NOLINT: type required by XGetWindowProperty
83 unsigned char* data_; 80 unsigned char* data_ = nullptr;
84 81
85 RTC_DISALLOW_COPY_AND_ASSIGN(XWindowProperty); 82 RTC_DISALLOW_COPY_AND_ASSIGN(XWindowProperty);
86 }; 83 };
87 84
88 class WindowCapturerLinux : public WindowCapturer, 85 class WindowCapturerLinux : public WindowCapturer,
89 public SharedXDisplay::XEventHandler { 86 public SharedXDisplay::XEventHandler {
90 public: 87 public:
91 WindowCapturerLinux(const DesktopCaptureOptions& options); 88 WindowCapturerLinux(const DesktopCaptureOptions& options);
92 virtual ~WindowCapturerLinux(); 89 virtual ~WindowCapturerLinux();
93 90
(...skipping 16 matching lines...) Expand all
110 // that has WM_STATE property set to NormalState. 107 // that has WM_STATE property set to NormalState.
111 // See http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.3.1 . 108 // See http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.3.1 .
112 ::Window GetApplicationWindow(::Window window); 109 ::Window GetApplicationWindow(::Window window);
113 110
114 // Returns true if the |window| is a desktop element. 111 // Returns true if the |window| is a desktop element.
115 bool IsDesktopElement(::Window window); 112 bool IsDesktopElement(::Window window);
116 113
117 // Returns window title for the specified X |window|. 114 // Returns window title for the specified X |window|.
118 bool GetWindowTitle(::Window window, std::string* title); 115 bool GetWindowTitle(::Window window, std::string* title);
119 116
120 Callback* callback_; 117 Callback* callback_ = nullptr;
121 118
122 rtc::scoped_refptr<SharedXDisplay> x_display_; 119 rtc::scoped_refptr<SharedXDisplay> x_display_;
123 120
124 Atom wm_state_atom_; 121 Atom wm_state_atom_;
125 Atom window_type_atom_; 122 Atom window_type_atom_;
126 Atom normal_window_type_atom_; 123 Atom normal_window_type_atom_;
127 bool has_composite_extension_; 124 bool has_composite_extension_ = false;
128 125
129 ::Window selected_window_; 126 ::Window selected_window_ = 0;
130 XServerPixelBuffer x_server_pixel_buffer_; 127 XServerPixelBuffer x_server_pixel_buffer_;
131 128
132 RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerLinux); 129 RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerLinux);
133 }; 130 };
134 131
135 WindowCapturerLinux::WindowCapturerLinux(const DesktopCaptureOptions& options) 132 WindowCapturerLinux::WindowCapturerLinux(const DesktopCaptureOptions& options)
136 : callback_(NULL), 133 : x_display_(options.x_display()) {
137 x_display_(options.x_display()),
138 has_composite_extension_(false),
139 selected_window_(0) {
140 // Create Atoms so we don't need to do it every time they are used. 134 // Create Atoms so we don't need to do it every time they are used.
141 wm_state_atom_ = XInternAtom(display(), "WM_STATE", True); 135 wm_state_atom_ = XInternAtom(display(), "WM_STATE", True);
142 window_type_atom_ = XInternAtom(display(), "_NET_WM_WINDOW_TYPE", True); 136 window_type_atom_ = XInternAtom(display(), "_NET_WM_WINDOW_TYPE", True);
143 normal_window_type_atom_ = XInternAtom( 137 normal_window_type_atom_ = XInternAtom(
144 display(), "_NET_WM_WINDOW_TYPE_NORMAL", True); 138 display(), "_NET_WM_WINDOW_TYPE_NORMAL", True);
145 139
146 int event_base, error_base, major_version, minor_version; 140 int event_base, error_base, major_version, minor_version;
147 if (XCompositeQueryExtension(display(), &event_base, &error_base) && 141 if (XCompositeQueryExtension(display(), &event_base, &error_base) &&
148 XCompositeQueryVersion(display(), &major_version, &minor_version) && 142 XCompositeQueryVersion(display(), &major_version, &minor_version) &&
149 // XCompositeNameWindowPixmap() requires version 0.2 143 // XCompositeNameWindowPixmap() requires version 0.2
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 void WindowCapturerLinux::Start(Callback* callback) { 267 void WindowCapturerLinux::Start(Callback* callback) {
274 assert(!callback_); 268 assert(!callback_);
275 assert(callback); 269 assert(callback);
276 270
277 callback_ = callback; 271 callback_ = callback;
278 } 272 }
279 273
280 void WindowCapturerLinux::Capture(const DesktopRegion& region) { 274 void WindowCapturerLinux::Capture(const DesktopRegion& region) {
281 if (!x_server_pixel_buffer_.IsWindowValid()) { 275 if (!x_server_pixel_buffer_.IsWindowValid()) {
282 LOG(LS_INFO) << "The window is no longer valid."; 276 LOG(LS_INFO) << "The window is no longer valid.";
283 callback_->OnCaptureCompleted(NULL); 277 callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr);
284 return; 278 return;
285 } 279 }
286 280
287 x_display_->ProcessPendingXEvents(); 281 x_display_->ProcessPendingXEvents();
288 282
289 if (!has_composite_extension_) { 283 if (!has_composite_extension_) {
290 // Without the Xcomposite extension we capture when the whole window is 284 // Without the Xcomposite extension we capture when the whole window is
291 // visible on screen and not covered by any other window. This is not 285 // visible on screen and not covered by any other window. This is not
292 // something we want so instead, just bail out. 286 // something we want so instead, just bail out.
293 LOG(LS_INFO) << "No Xcomposite extension detected."; 287 LOG(LS_INFO) << "No Xcomposite extension detected.";
294 callback_->OnCaptureCompleted(NULL); 288 callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr);
295 return; 289 return;
296 } 290 }
297 291
298 DesktopFrame* frame = 292 std::unique_ptr<DesktopFrame> frame(
299 new BasicDesktopFrame(x_server_pixel_buffer_.window_size()); 293 new BasicDesktopFrame(x_server_pixel_buffer_.window_size()));
300 294
301 x_server_pixel_buffer_.Synchronize(); 295 x_server_pixel_buffer_.Synchronize();
302 x_server_pixel_buffer_.CaptureRect(DesktopRect::MakeSize(frame->size()), 296 x_server_pixel_buffer_.CaptureRect(DesktopRect::MakeSize(frame->size()),
303 frame); 297 frame.get());
304 298
305 frame->mutable_updated_region()->SetRect( 299 frame->mutable_updated_region()->SetRect(
306 DesktopRect::MakeSize(frame->size())); 300 DesktopRect::MakeSize(frame->size()));
307 301
308 callback_->OnCaptureCompleted(frame); 302 callback_->OnCaptureResult(Result::SUCCESS, std::move(frame));
309 } 303 }
310 304
311 bool WindowCapturerLinux::HandleXEvent(const XEvent& event) { 305 bool WindowCapturerLinux::HandleXEvent(const XEvent& event) {
312 if (event.type == ConfigureNotify) { 306 if (event.type == ConfigureNotify) {
313 XConfigureEvent xce = event.xconfigure; 307 XConfigureEvent xce = event.xconfigure;
314 if (!DesktopSize(xce.width, xce.height).equals( 308 if (!DesktopSize(xce.width, xce.height).equals(
315 x_server_pixel_buffer_.window_size())) { 309 x_server_pixel_buffer_.window_size())) {
316 if (!x_server_pixel_buffer_.Init(display(), selected_window_)) { 310 if (!x_server_pixel_buffer_.Init(display(), selected_window_)) {
317 LOG(LS_ERROR) << "Failed to initialize pixel buffer after resizing."; 311 LOG(LS_ERROR) << "Failed to initialize pixel buffer after resizing.";
318 } 312 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 } 386 }
393 XFree(class_hint.res_name); 387 XFree(class_hint.res_name);
394 XFree(class_hint.res_class); 388 XFree(class_hint.res_class);
395 return result; 389 return result;
396 } 390 }
397 391
398 bool WindowCapturerLinux::GetWindowTitle(::Window window, std::string* title) { 392 bool WindowCapturerLinux::GetWindowTitle(::Window window, std::string* title) {
399 int status; 393 int status;
400 bool result = false; 394 bool result = false;
401 XTextProperty window_name; 395 XTextProperty window_name;
402 window_name.value = NULL; 396 window_name.value = nullptr;
403 if (window) { 397 if (window) {
404 status = XGetWMName(display(), window, &window_name); 398 status = XGetWMName(display(), window, &window_name);
405 if (status && window_name.value && window_name.nitems) { 399 if (status && window_name.value && window_name.nitems) {
406 int cnt; 400 int cnt;
407 char **list = NULL; 401 char** list = nullptr;
408 status = Xutf8TextPropertyToTextList(display(), &window_name, &list, 402 status = Xutf8TextPropertyToTextList(display(), &window_name, &list,
409 &cnt); 403 &cnt);
410 if (status >= Success && cnt && *list) { 404 if (status >= Success && cnt && *list) {
411 if (cnt > 1) { 405 if (cnt > 1) {
412 LOG(LS_INFO) << "Window has " << cnt 406 LOG(LS_INFO) << "Window has " << cnt
413 << " text properties, only using the first one."; 407 << " text properties, only using the first one.";
414 } 408 }
415 *title = *list; 409 *title = *list;
416 result = true; 410 result = true;
417 } 411 }
418 if (list) 412 if (list)
419 XFreeStringList(list); 413 XFreeStringList(list);
420 } 414 }
421 if (window_name.value) 415 if (window_name.value)
422 XFree(window_name.value); 416 XFree(window_name.value);
423 } 417 }
424 return result; 418 return result;
425 } 419 }
426 420
427 } // namespace 421 } // namespace
428 422
429 // static 423 // static
430 WindowCapturer* WindowCapturer::Create(const DesktopCaptureOptions& options) { 424 WindowCapturer* WindowCapturer::Create(const DesktopCaptureOptions& options) {
431 if (!options.x_display()) 425 if (!options.x_display())
432 return NULL; 426 return nullptr;
433 return new WindowCapturerLinux(options); 427 return new WindowCapturerLinux(options);
434 } 428 }
435 429
436 } // namespace webrtc 430 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/desktop_capture/window_capturer_win.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698