From 70fbbad5ac65d6c20b1deb82c98c9fc0f880988c Mon Sep 17 00:00:00 2001 From: Zijie He Date: Tue, 15 Aug 2017 15:45:00 -0700 Subject: [PATCH] Replace WindowUnderPoint free function with WindowFinder interface WindowUnderPoint have different signatures on different platforms, which should be abstract as an interface. So this change adds a WindowFinder interface to replace WindowUnderPoint free function. Meanwhile, this change also includes the implementation of WindowFinderX11 for X11. Bug: webrtc:7950 Change-Id: I897a50d4033e713b339b6b6f48b5dbbe601e8db0 Reviewed-on: https://chromium-review.googlesource.com/611745 Reviewed-by: Jamie Walch Commit-Queue: Zijie He Cr-Commit-Position: refs/heads/master@{#19375} --- webrtc/modules/desktop_capture/BUILD.gn | 11 +++-- .../desktop_capture/window_capturer_x11.cc | 13 +++--- .../modules/desktop_capture/window_finder.h | 33 +++++++++++++++ .../desktop_capture/window_finder_mac.h | 30 ++++++++++++++ .../desktop_capture/window_finder_mac.mm | 36 +++++++++++++++++ ...nder_point_win.cc => window_finder_win.cc} | 7 +++- .../desktop_capture/window_finder_win.h | 30 ++++++++++++++ .../desktop_capture/window_finder_x11.cc | 40 +++++++++++++++++++ .../desktop_capture/window_finder_x11.h | 35 ++++++++++++++++ .../desktop_capture/window_under_point.h | 26 ------------ .../window_under_point_linux.cc | 20 ---------- .../desktop_capture/window_under_point_mac.mm | 34 ---------------- .../desktop_capture/x11/window_list_utils.cc | 21 ++++++++++ .../desktop_capture/x11/window_list_utils.h | 18 +++++++++ .../x11/x_server_pixel_buffer.cc | 22 +++++----- .../x11/x_server_pixel_buffer.h | 7 +++- 16 files changed, 277 insertions(+), 106 deletions(-) create mode 100644 webrtc/modules/desktop_capture/window_finder.h create mode 100644 webrtc/modules/desktop_capture/window_finder_mac.h create mode 100644 webrtc/modules/desktop_capture/window_finder_mac.mm rename webrtc/modules/desktop_capture/{window_under_point_win.cc => window_finder_win.cc} (81%) create mode 100644 webrtc/modules/desktop_capture/window_finder_win.h create mode 100644 webrtc/modules/desktop_capture/window_finder_x11.cc create mode 100644 webrtc/modules/desktop_capture/window_finder_x11.h delete mode 100644 webrtc/modules/desktop_capture/window_under_point.h delete mode 100644 webrtc/modules/desktop_capture/window_under_point_linux.cc delete mode 100644 webrtc/modules/desktop_capture/window_under_point_mac.mm diff --git a/webrtc/modules/desktop_capture/BUILD.gn b/webrtc/modules/desktop_capture/BUILD.gn index 019f39dd20..caf27a364b 100644 --- a/webrtc/modules/desktop_capture/BUILD.gn +++ b/webrtc/modules/desktop_capture/BUILD.gn @@ -251,10 +251,11 @@ rtc_static_library("desktop_capture") { "win/window_capture_utils.h", "window_capturer_mac.mm", "window_capturer_win.cc", - "window_under_point.h", - "window_under_point_linux.cc", - "window_under_point_mac.mm", - "window_under_point_win.cc", + "window_finder.h", + "window_finder_mac.h", + "window_finder_mac.mm", + "window_finder_win.cc", + "window_finder_win.h", ] if (use_x11) { @@ -262,6 +263,8 @@ rtc_static_library("desktop_capture") { "mouse_cursor_monitor_x11.cc", "screen_capturer_x11.cc", "window_capturer_x11.cc", + "window_finder_x11.cc", + "window_finder_x11.h", "x11/shared_x_display.cc", "x11/shared_x_display.h", "x11/window_list_utils.cc", diff --git a/webrtc/modules/desktop_capture/window_capturer_x11.cc b/webrtc/modules/desktop_capture/window_capturer_x11.cc index eb4ece19aa..3ea69a1137 100644 --- a/webrtc/modules/desktop_capture/window_capturer_x11.cc +++ b/webrtc/modules/desktop_capture/window_capturer_x11.cc @@ -219,14 +219,17 @@ void WindowCapturerLinux::CaptureFrame() { bool WindowCapturerLinux::HandleXEvent(const XEvent& event) { if (event.type == ConfigureNotify) { XConfigureEvent xce = event.xconfigure; - if (!DesktopSize(xce.width, xce.height).equals( - x_server_pixel_buffer_.window_size())) { - if (!x_server_pixel_buffer_.Init(display(), selected_window_)) { - LOG(LS_ERROR) << "Failed to initialize pixel buffer after resizing."; + if (xce.window == selected_window_) { + if (!DesktopRectFromXAttributes(xce).equals( + x_server_pixel_buffer_.window_rect())) { + if (!x_server_pixel_buffer_.Init(display(), selected_window_)) { + LOG(LS_ERROR) << "Failed to initialize pixel buffer after resizing."; + } } - return true; } } + + // Always returns false, so other observers can still receive the events. return false; } diff --git a/webrtc/modules/desktop_capture/window_finder.h b/webrtc/modules/desktop_capture/window_finder.h new file mode 100644 index 0000000000..4c46c48e94 --- /dev/null +++ b/webrtc/modules/desktop_capture/window_finder.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_WINDOW_FINDER_H_ +#define WEBRTC_MODULES_DESKTOP_CAPTURE_WINDOW_FINDER_H_ + +#include "webrtc/modules/desktop_capture/desktop_capture_types.h" +#include "webrtc/modules/desktop_capture/desktop_geometry.h" + +namespace webrtc { + +// An interface to return the id of the visible window under a certain point. +class WindowFinder { + public: + WindowFinder() = default; + virtual ~WindowFinder() = default; + + // Returns the id of the visible window under |point|. This function returns + // kNullWindowId if no window is under |point| and the platform does not have + // "root window" concept, i.e. the visible area under |point| is the desktop. + virtual WindowId GetWindowUnderPoint(DesktopVector point) = 0; +}; + +} // namespace webrtc + +#endif // WEBRTC_MODULES_DESKTOP_CAPTURE_WINDOW_FINDER_H_ diff --git a/webrtc/modules/desktop_capture/window_finder_mac.h b/webrtc/modules/desktop_capture/window_finder_mac.h new file mode 100644 index 0000000000..4b01600e82 --- /dev/null +++ b/webrtc/modules/desktop_capture/window_finder_mac.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_WINDOW_FINDER_MAC_H_ +#define WEBRTC_MODULES_DESKTOP_CAPTURE_WINDOW_FINDER_MAC_H_ + +#include "webrtc/modules/desktop_capture/window_finder.h" + +namespace webrtc { + +// The implementation of WindowFinder for Windows. +class WindowFinderMac final : public WindowFinder { + public: + WindowFinderMac(); + ~WindowFinderMac() override; + + // WindowFinder implementation. + WindowId GetWindowUnderPoint(DesktopVector point) override; +}; + +} // namespace webrtc + +#endif // WEBRTC_MODULES_DESKTOP_CAPTURE_WINDOW_FINDER_MAC_H_ diff --git a/webrtc/modules/desktop_capture/window_finder_mac.mm b/webrtc/modules/desktop_capture/window_finder_mac.mm new file mode 100644 index 0000000000..ae4a911c7b --- /dev/null +++ b/webrtc/modules/desktop_capture/window_finder_mac.mm @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/modules/desktop_capture/window_finder_mac.h" + +#include + +#include "webrtc/modules/desktop_capture/mac/window_list_utils.h" + +namespace webrtc { + +WindowFinderMac::WindowFinderMac() = default; +WindowFinderMac::~WindowFinderMac() = default; + +WindowId WindowFinderMac::GetWindowUnderPoint(DesktopVector point) { + WindowId id = kNullWindowId; + GetWindowList([&id, point](CFDictionaryRef window) { + DesktopRect bounds = GetWindowBounds(window); + if (bounds.Contains(point)) { + id = GetWindowId(window); + return false; + } + return true; + }, + true); + return id; +} + +} // namespace webrtc diff --git a/webrtc/modules/desktop_capture/window_under_point_win.cc b/webrtc/modules/desktop_capture/window_finder_win.cc similarity index 81% rename from webrtc/modules/desktop_capture/window_under_point_win.cc rename to webrtc/modules/desktop_capture/window_finder_win.cc index a5e7dc1d8f..8d742cda98 100644 --- a/webrtc/modules/desktop_capture/window_under_point_win.cc +++ b/webrtc/modules/desktop_capture/window_finder_win.cc @@ -8,13 +8,16 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/desktop_capture/window_under_point.h" +#include "webrtc/modules/desktop_capture/window_finder_win.h" #include namespace webrtc { -WindowId GetWindowUnderPoint(DesktopVector point) { +WindowFinderWin::WindowFinderWin() = default; +WindowFinderWin::~WindowFinderWin() = default; + +WindowId WindowFinderWin::GetWindowUnderPoint(DesktopVector point) { HWND window = WindowFromPoint(POINT { point.x(), point.y() }); if (!window) { return kNullWindowId; diff --git a/webrtc/modules/desktop_capture/window_finder_win.h b/webrtc/modules/desktop_capture/window_finder_win.h new file mode 100644 index 0000000000..ceec42690c --- /dev/null +++ b/webrtc/modules/desktop_capture/window_finder_win.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_WINDOW_FINDER_WIN_H_ +#define WEBRTC_MODULES_DESKTOP_CAPTURE_WINDOW_FINDER_WIN_H_ + +#include "webrtc/modules/desktop_capture/window_finder.h" + +namespace webrtc { + +// The implementation of WindowFinder for Windows. +class WindowFinderWin final : public WindowFinder { + public: + WindowFinderWin(); + ~WindowFinderWin() override; + + // WindowFinder implementation. + WindowId GetWindowUnderPoint(DesktopVector point) override; +}; + +} // namespace webrtc + +#endif // WEBRTC_MODULES_DESKTOP_CAPTURE_WINDOW_FINDER_WIN_H_ diff --git a/webrtc/modules/desktop_capture/window_finder_x11.cc b/webrtc/modules/desktop_capture/window_finder_x11.cc new file mode 100644 index 0000000000..4c6da9d74e --- /dev/null +++ b/webrtc/modules/desktop_capture/window_finder_x11.cc @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/modules/desktop_capture/window_finder_x11.h" + +#include "webrtc/modules/desktop_capture/x11/window_list_utils.h" +#include "webrtc/rtc_base/checks.h" + +namespace webrtc { + +WindowFinderX11::WindowFinderX11(XAtomCache* cache) + : cache_(cache) { + RTC_DCHECK(cache_); +} + +WindowFinderX11::~WindowFinderX11() = default; + +WindowId WindowFinderX11::GetWindowUnderPoint(DesktopVector point) { + WindowId id = kNullWindowId; + GetWindowList(cache_, + [&id, this, point](::Window window) { + DesktopRect rect; + if (GetWindowRect(this->cache_->display(), window, &rect) && + rect.Contains(point)) { + id = window; + return false; + } + return true; + }); + return id; +} + +} // namespace webrtc diff --git a/webrtc/modules/desktop_capture/window_finder_x11.h b/webrtc/modules/desktop_capture/window_finder_x11.h new file mode 100644 index 0000000000..9a4e020214 --- /dev/null +++ b/webrtc/modules/desktop_capture/window_finder_x11.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_WINDOW_FINDER_X11_H_ +#define WEBRTC_MODULES_DESKTOP_CAPTURE_WINDOW_FINDER_X11_H_ + +#include "webrtc/modules/desktop_capture/window_finder.h" + +namespace webrtc { + +class XAtomCache; + +// The implementation of WindowFinder for Windows. +class WindowFinderX11 final : public WindowFinder { + public: + explicit WindowFinderX11(XAtomCache* cache); + ~WindowFinderX11() override; + + // WindowFinder implementation. + WindowId GetWindowUnderPoint(DesktopVector point) override; + + private: + XAtomCache* const cache_; +}; + +} // namespace webrtc + +#endif // WEBRTC_MODULES_DESKTOP_CAPTURE_WINDOW_FINDER_X11_H_ diff --git a/webrtc/modules/desktop_capture/window_under_point.h b/webrtc/modules/desktop_capture/window_under_point.h deleted file mode 100644 index 5e61207c57..0000000000 --- a/webrtc/modules/desktop_capture/window_under_point.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_WINDOW_UNDER_POINT_H_ -#define WEBRTC_MODULES_DESKTOP_CAPTURE_WINDOW_UNDER_POINT_H_ - -#include "webrtc/modules/desktop_capture/desktop_capture_types.h" -#include "webrtc/modules/desktop_capture/desktop_geometry.h" - -namespace webrtc { - -// Returns the id of the visible window under |point|. This function returns -// kNullWindowId if no window is under |point| and the platform does not have -// "root window" concept, i.e. the visible area under |point| is the desktop. -WindowId GetWindowUnderPoint(DesktopVector point); - -} // namespace webrtc - -#endif // WEBRTC_MODULES_DESKTOP_CAPTURE_WINDOW_UNDER_POINT_H_ diff --git a/webrtc/modules/desktop_capture/window_under_point_linux.cc b/webrtc/modules/desktop_capture/window_under_point_linux.cc deleted file mode 100644 index 7b1d0f70ef..0000000000 --- a/webrtc/modules/desktop_capture/window_under_point_linux.cc +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/desktop_capture/window_under_point.h" - -namespace webrtc { - -WindowId GetWindowUnderPoint(DesktopVector point) { - // TODO(zijiehe): Implementation required. - return kNullWindowId; -} - -} // namespace webrtc diff --git a/webrtc/modules/desktop_capture/window_under_point_mac.mm b/webrtc/modules/desktop_capture/window_under_point_mac.mm deleted file mode 100644 index 7fe57f32cb..0000000000 --- a/webrtc/modules/desktop_capture/window_under_point_mac.mm +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include "webrtc/modules/desktop_capture/mac/window_list_utils.h" -#include "webrtc/modules/desktop_capture/window_under_point.h" - -namespace webrtc { - -WindowId GetWindowUnderPoint(DesktopVector point) { - WindowId id; - if (!GetWindowList([&id, point](CFDictionaryRef window) { - DesktopRect bounds = GetWindowBounds(window); - if (bounds.Contains(point)) { - id = GetWindowId(window); - return false; - } - return true; - }, - true)) { - return kNullWindowId; - } - return id; -} - -} // namespace webrtc diff --git a/webrtc/modules/desktop_capture/x11/window_list_utils.cc b/webrtc/modules/desktop_capture/x11/window_list_utils.cc index 1148acc5fb..f71779d099 100644 --- a/webrtc/modules/desktop_capture/x11/window_list_utils.cc +++ b/webrtc/modules/desktop_capture/x11/window_list_utils.cc @@ -216,4 +216,25 @@ bool GetWindowList(XAtomCache* cache, return failed_screens < num_screens; } +bool GetWindowRect(::Display* display, + ::Window window, + DesktopRect* rect, + XWindowAttributes* attributes /* = nullptr */) { + XWindowAttributes local_attributes; + if (attributes == nullptr) { + attributes = &local_attributes; + } + + { + XErrorTrap error_trap(display); + if (!XGetWindowAttributes(display, window, attributes) || + error_trap.GetLastErrorAndDisable() != 0) { + return false; + } + } + + *rect = DesktopRectFromXAttributes(*attributes); + return true; +} + } // namespace webrtc diff --git a/webrtc/modules/desktop_capture/x11/window_list_utils.h b/webrtc/modules/desktop_capture/x11/window_list_utils.h index 8a64594457..f7c4b5e3f2 100644 --- a/webrtc/modules/desktop_capture/x11/window_list_utils.h +++ b/webrtc/modules/desktop_capture/x11/window_list_utils.h @@ -13,6 +13,7 @@ #include +#include "webrtc/modules/desktop_capture/desktop_geometry.h" #include "webrtc/modules/desktop_capture/x11/x_atom_cache.h" #include "webrtc/rtc_base/function_view.h" @@ -32,6 +33,23 @@ bool GetWindowList(XAtomCache* cache, // WithdrawnState if the |window| is missing. int32_t GetWindowState(XAtomCache* cache, ::Window window); +// Returns the rectangle of the |window| in the coordinates of |display|. This +// function returns false if native APIs failed. If |attributes| is provided, it +// will be filled with the attributes of |window|. +bool GetWindowRect(::Display* display, + ::Window window, + DesktopRect* rect, + XWindowAttributes* attributes = nullptr); + +// Creates a DesktopRect from |attributes|. +template +DesktopRect DesktopRectFromXAttributes(const T& attributes) { + return DesktopRect::MakeXYWH(attributes.x, + attributes.y, + attributes.width, + attributes.height); +} + } // namespace webrtc #endif // WEBRTC_MODULES_DESKTOP_CAPTURE_X11_WINDOW_LIST_UTILS_H_ diff --git a/webrtc/modules/desktop_capture/x11/x_server_pixel_buffer.cc b/webrtc/modules/desktop_capture/x11/x_server_pixel_buffer.cc index 26c334eafd..5068802da6 100644 --- a/webrtc/modules/desktop_capture/x11/x_server_pixel_buffer.cc +++ b/webrtc/modules/desktop_capture/x11/x_server_pixel_buffer.cc @@ -10,12 +10,13 @@ #include "webrtc/modules/desktop_capture/x11/x_server_pixel_buffer.h" -#include #include #include #include "webrtc/modules/desktop_capture/desktop_frame.h" +#include "webrtc/modules/desktop_capture/x11/window_list_utils.h" #include "webrtc/modules/desktop_capture/x11/x_error_trap.h" +#include "webrtc/rtc_base/checks.h" #include "webrtc/rtc_base/logging.h" namespace webrtc { @@ -175,15 +176,10 @@ bool XServerPixelBuffer::Init(Display* display, Window window) { display_ = display; XWindowAttributes attributes; - { - XErrorTrap error_trap(display_); - if (!XGetWindowAttributes(display_, window, &attributes) || - error_trap.GetLastErrorAndDisable() != 0) { - return false; - } + if (!GetWindowRect(display_, window, &window_rect_, &attributes)) { + return false; } - window_size_ = DesktopSize(attributes.width, attributes.height); window_ = window; InitShm(attributes); @@ -208,7 +204,7 @@ void XServerPixelBuffer::InitShm(const XWindowAttributes& attributes) { shm_segment_info_->readOnly = False; x_shm_image_ = XShmCreateImage(display_, default_visual, default_depth, ZPixmap, 0, shm_segment_info_, - window_size_.width(), window_size_.height()); + window_rect_.width(), window_rect_.height()); if (x_shm_image_) { shm_segment_info_->shmid = shmget(IPC_PRIVATE, x_shm_image_->bytes_per_line * x_shm_image_->height, @@ -261,8 +257,8 @@ bool XServerPixelBuffer::InitPixmaps(int depth) { shm_pixmap_ = XShmCreatePixmap(display_, window_, shm_segment_info_->shmaddr, shm_segment_info_, - window_size_.width(), - window_size_.height(), depth); + window_rect_.width(), + window_rect_.height(), depth); XSync(display_, False); if (error_trap.GetLastErrorAndDisable() != 0) { // |shm_pixmap_| is not not valid because the request was not processed @@ -316,8 +312,8 @@ void XServerPixelBuffer::Synchronize() { bool XServerPixelBuffer::CaptureRect(const DesktopRect& rect, DesktopFrame* frame) { - assert(rect.right() <= window_size_.width()); - assert(rect.bottom() <= window_size_.height()); + RTC_DCHECK_LE(rect.right(), window_rect_.width()); + RTC_DCHECK_LE(rect.bottom(), window_rect_.height()); XImage* image; uint8_t* data; diff --git a/webrtc/modules/desktop_capture/x11/x_server_pixel_buffer.h b/webrtc/modules/desktop_capture/x11/x_server_pixel_buffer.h index 5a4cf2180d..305b8e1650 100644 --- a/webrtc/modules/desktop_capture/x11/x_server_pixel_buffer.h +++ b/webrtc/modules/desktop_capture/x11/x_server_pixel_buffer.h @@ -39,7 +39,10 @@ class XServerPixelBuffer { bool is_initialized() { return window_ != 0; } // Returns the size of the window the buffer was initialized for. - const DesktopSize& window_size() { return window_size_; } + DesktopSize window_size() { return window_rect_.size(); } + + // Returns the rectangle of the window the buffer was initialized for. + const DesktopRect& window_rect() { return window_rect_; } // Returns true if the window can be found. bool IsWindowValid() const; @@ -65,7 +68,7 @@ class XServerPixelBuffer { Display* display_ = nullptr; Window window_ = 0; - DesktopSize window_size_; + DesktopRect window_rect_; XImage* x_image_ = nullptr; XShmSegmentInfo* shm_segment_info_ = nullptr; XImage* x_shm_image_ = nullptr;