| 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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 // that has WM_STATE property set to NormalState. | 104 // that has WM_STATE property set to NormalState. |
| 105 // See http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.3.1 . | 105 // See http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.3.1 . |
| 106 ::Window GetApplicationWindow(::Window window); | 106 ::Window GetApplicationWindow(::Window window); |
| 107 | 107 |
| 108 // Returns true if the |window| is a desktop element. | 108 // Returns true if the |window| is a desktop element. |
| 109 bool IsDesktopElement(::Window window); | 109 bool IsDesktopElement(::Window window); |
| 110 | 110 |
| 111 // Returns window title for the specified X |window|. | 111 // Returns window title for the specified X |window|. |
| 112 bool GetWindowTitle(::Window window, std::string* title); | 112 bool GetWindowTitle(::Window window, std::string* title); |
| 113 | 113 |
| 114 // Return WM_STATE property of the |window|. |
| 115 int32_t GetWindowState(::Window window); |
| 116 |
| 114 Callback* callback_ = nullptr; | 117 Callback* callback_ = nullptr; |
| 115 | 118 |
| 116 rtc::scoped_refptr<SharedXDisplay> x_display_; | 119 rtc::scoped_refptr<SharedXDisplay> x_display_; |
| 117 | 120 |
| 118 Atom wm_state_atom_; | 121 Atom wm_state_atom_; |
| 119 Atom window_type_atom_; | 122 Atom window_type_atom_; |
| 120 Atom normal_window_type_atom_; | 123 Atom normal_window_type_atom_; |
| 121 bool has_composite_extension_ = false; | 124 bool has_composite_extension_ = false; |
| 122 | 125 |
| 123 ::Window selected_window_ = 0; | 126 ::Window selected_window_ = 0; |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 | 282 |
| 280 if (!has_composite_extension_) { | 283 if (!has_composite_extension_) { |
| 281 // Without the Xcomposite extension we capture when the whole window is | 284 // Without the Xcomposite extension we capture when the whole window is |
| 282 // 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 |
| 283 // something we want so instead, just bail out. | 286 // something we want so instead, just bail out. |
| 284 LOG(LS_INFO) << "No Xcomposite extension detected."; | 287 LOG(LS_INFO) << "No Xcomposite extension detected."; |
| 285 callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); | 288 callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); |
| 286 return; | 289 return; |
| 287 } | 290 } |
| 288 | 291 |
| 292 if (GetWindowState(selected_window_) == IconicState) { |
| 293 // Window is in minimized. Return a 1x1 frame as same as OSX/Win does. |
| 294 std::unique_ptr<DesktopFrame> frame( |
| 295 new BasicDesktopFrame(DesktopSize(1, 1))); |
| 296 callback_->OnCaptureResult(Result::SUCCESS, std::move(frame)); |
| 297 return; |
| 298 } |
| 299 |
| 289 std::unique_ptr<DesktopFrame> frame( | 300 std::unique_ptr<DesktopFrame> frame( |
| 290 new BasicDesktopFrame(x_server_pixel_buffer_.window_size())); | 301 new BasicDesktopFrame(x_server_pixel_buffer_.window_size())); |
| 291 | 302 |
| 292 x_server_pixel_buffer_.Synchronize(); | 303 x_server_pixel_buffer_.Synchronize(); |
| 293 if (!x_server_pixel_buffer_.CaptureRect(DesktopRect::MakeSize(frame->size()), | 304 if (!x_server_pixel_buffer_.CaptureRect(DesktopRect::MakeSize(frame->size()), |
| 294 frame.get())) { | 305 frame.get())) { |
| 295 callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); | 306 callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); |
| 296 return; | 307 return; |
| 297 } | 308 } |
| 298 | 309 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 310 if (!x_server_pixel_buffer_.Init(display(), selected_window_)) { | 321 if (!x_server_pixel_buffer_.Init(display(), selected_window_)) { |
| 311 LOG(LS_ERROR) << "Failed to initialize pixel buffer after resizing."; | 322 LOG(LS_ERROR) << "Failed to initialize pixel buffer after resizing."; |
| 312 } | 323 } |
| 313 return true; | 324 return true; |
| 314 } | 325 } |
| 315 } | 326 } |
| 316 return false; | 327 return false; |
| 317 } | 328 } |
| 318 | 329 |
| 319 ::Window WindowCapturerLinux::GetApplicationWindow(::Window window) { | 330 ::Window WindowCapturerLinux::GetApplicationWindow(::Window window) { |
| 320 // Get WM_STATE property of the window. | 331 int32_t state = GetWindowState(window); |
| 321 XWindowProperty<uint32_t> window_state(display(), window, wm_state_atom_); | |
| 322 | |
| 323 // WM_STATE is considered to be set to WithdrawnState when it missing. | |
| 324 int32_t state = window_state.is_valid() ? | |
| 325 *window_state.data() : WithdrawnState; | |
| 326 | |
| 327 if (state == NormalState) { | 332 if (state == NormalState) { |
| 328 // Window has WM_STATE==NormalState. Return it. | 333 // Window has WM_STATE==NormalState. Return it. |
| 329 return window; | 334 return window; |
| 330 } else if (state == IconicState) { | 335 } else if (state == IconicState) { |
| 331 // Window is in minimized. Skip it. | 336 // Window is in minimized. Skip it. |
| 332 return 0; | 337 return 0; |
| 333 } | 338 } |
| 334 | 339 |
| 335 // If the window is in WithdrawnState then look at all of its children. | 340 // If the window is in WithdrawnState then look at all of its children. |
| 336 ::Window root, parent; | 341 ::Window root, parent; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 } | 416 } |
| 412 if (list) | 417 if (list) |
| 413 XFreeStringList(list); | 418 XFreeStringList(list); |
| 414 } | 419 } |
| 415 if (window_name.value) | 420 if (window_name.value) |
| 416 XFree(window_name.value); | 421 XFree(window_name.value); |
| 417 } | 422 } |
| 418 return result; | 423 return result; |
| 419 } | 424 } |
| 420 | 425 |
| 426 int32_t WindowCapturerLinux::GetWindowState(::Window window) { |
| 427 // Get WM_STATE property of the window. |
| 428 XWindowProperty<uint32_t> window_state(display(), window, wm_state_atom_); |
| 429 |
| 430 // WM_STATE is considered to be set to WithdrawnState when it missing. |
| 431 return window_state.is_valid() ? *window_state.data() : WithdrawnState; |
| 432 } |
| 433 |
| 421 } // namespace | 434 } // namespace |
| 422 | 435 |
| 423 // static | 436 // static |
| 424 std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawWindowCapturer( | 437 std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawWindowCapturer( |
| 425 const DesktopCaptureOptions& options) { | 438 const DesktopCaptureOptions& options) { |
| 426 if (!options.x_display()) | 439 if (!options.x_display()) |
| 427 return nullptr; | 440 return nullptr; |
| 428 return std::unique_ptr<DesktopCapturer>(new WindowCapturerLinux(options)); | 441 return std::unique_ptr<DesktopCapturer>(new WindowCapturerLinux(options)); |
| 429 } | 442 } |
| 430 | 443 |
| 431 } // namespace webrtc | 444 } // namespace webrtc |
| OLD | NEW |