From bbc747c116c731c6f6fbcc4dd1d98da520c03179 Mon Sep 17 00:00:00 2001 From: nisse Date: Fri, 18 Nov 2016 02:46:20 -0800 Subject: [PATCH] Delete WindowPicker class and subclasses. BUG=webrtc:6424 Review-Url: https://codereview.webrtc.org/2511103002 Cr-Commit-Position: refs/heads/master@{#15151} --- webrtc/BUILD.gn | 4 - webrtc/base/BUILD.gn | 15 - webrtc/base/macwindowpicker.cc | 189 ----- webrtc/base/macwindowpicker.h | 38 - webrtc/base/macwindowpicker_unittest.cc | 45 -- webrtc/base/win32windowpicker.cc | 144 ---- webrtc/base/win32windowpicker.h | 39 -- webrtc/base/win32windowpicker_unittest.cc | 100 --- webrtc/base/windowpicker.h | 84 --- webrtc/base/windowpicker_unittest.cc | 69 -- webrtc/base/windowpickerfactory.h | 59 -- webrtc/base/x11windowpicker.cc | 816 ---------------------- webrtc/base/x11windowpicker.h | 53 -- webrtc/base/x11windowpicker_unittest.cc | 40 -- 14 files changed, 1695 deletions(-) delete mode 100644 webrtc/base/macwindowpicker.cc delete mode 100644 webrtc/base/macwindowpicker.h delete mode 100644 webrtc/base/macwindowpicker_unittest.cc delete mode 100644 webrtc/base/win32windowpicker.cc delete mode 100644 webrtc/base/win32windowpicker.h delete mode 100644 webrtc/base/win32windowpicker_unittest.cc delete mode 100644 webrtc/base/windowpicker.h delete mode 100644 webrtc/base/windowpicker_unittest.cc delete mode 100644 webrtc/base/windowpickerfactory.h delete mode 100644 webrtc/base/x11windowpicker.cc delete mode 100644 webrtc/base/x11windowpicker.h delete mode 100644 webrtc/base/x11windowpicker_unittest.cc diff --git a/webrtc/BUILD.gn b/webrtc/BUILD.gn index 1d14c906f3..f8a271d407 100644 --- a/webrtc/BUILD.gn +++ b/webrtc/BUILD.gn @@ -455,9 +455,6 @@ if (rtc_include_tests) { "base/timeutils_unittest.cc", "base/urlencode_unittest.cc", "base/weak_ptr_unittest.cc", - - # TODO(ronghuawu): Reenable this test. - # "windowpicker_unittest.cc", "p2p/base/asyncstuntcpsocket_unittest.cc", "p2p/base/dtlstransportchannel_unittest.cc", "p2p/base/fakeportallocator.h", @@ -501,7 +498,6 @@ if (rtc_include_tests) { "base/win32_unittest.cc", "base/win32regkey_unittest.cc", "base/win32window_unittest.cc", - "base/win32windowpicker_unittest.cc", ] } diff --git a/webrtc/base/BUILD.gn b/webrtc/base/BUILD.gn index e0f6b8282f..d060070b44 100644 --- a/webrtc/base/BUILD.gn +++ b/webrtc/base/BUILD.gn @@ -559,8 +559,6 @@ rtc_static_library("rtc_base") { "virtualsocketserver.cc", "virtualsocketserver.h", "window.h", - "windowpicker.h", - "windowpickerfactory.h", ] if (is_linux) { @@ -581,13 +579,6 @@ rtc_static_library("rtc_base") { ] } - if (is_mac) { - sources += [ - "macwindowpicker.cc", - "macwindowpicker.h", - ] - } - if (is_win) { sources += [ "diskcache_win32.cc", @@ -643,10 +634,6 @@ rtc_static_library("rtc_base") { } if (use_x11) { - sources += [ - "x11windowpicker.cc", - "x11windowpicker.h", - ] libs += [ "dl", "rt", @@ -684,8 +671,6 @@ rtc_static_library("rtc_base") { "win32securityerrors.cc", "win32window.cc", "win32window.h", - "win32windowpicker.cc", - "win32windowpicker.h", "winping.cc", "winping.h", ] diff --git a/webrtc/base/macwindowpicker.cc b/webrtc/base/macwindowpicker.cc deleted file mode 100644 index d43d0e8cbf..0000000000 --- a/webrtc/base/macwindowpicker.cc +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright 2010 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/base/macwindowpicker.h" - -#include -#include -#include - -#include "webrtc/base/logging.h" -#include "webrtc/base/macutils.h" - -namespace rtc { - -static const char* kCoreGraphicsName = - "/System/Library/Frameworks/ApplicationServices.framework/Frameworks/" - "CoreGraphics.framework/CoreGraphics"; - -static const char* kWindowListCopyWindowInfo = "CGWindowListCopyWindowInfo"; -static const char* kWindowListCreateDescriptionFromArray = - "CGWindowListCreateDescriptionFromArray"; - -// Function pointer for holding the CGWindowListCopyWindowInfo function. -typedef CFArrayRef(*CGWindowListCopyWindowInfoProc)(CGWindowListOption, - CGWindowID); - -// Function pointer for holding the CGWindowListCreateDescriptionFromArray -// function. -typedef CFArrayRef(*CGWindowListCreateDescriptionFromArrayProc)(CFArrayRef); - -MacWindowPicker::MacWindowPicker() : lib_handle_(NULL), get_window_list_(NULL), - get_window_list_desc_(NULL) { -} - -MacWindowPicker::~MacWindowPicker() { - if (lib_handle_ != NULL) { - dlclose(lib_handle_); - } -} - -bool MacWindowPicker::Init() { - // TODO: If this class grows to use more dynamically functions - // from the CoreGraphics framework, consider using - // webrtc/base/latebindingsymboltable.h. - lib_handle_ = dlopen(kCoreGraphicsName, RTLD_NOW); - if (lib_handle_ == NULL) { - LOG(LS_ERROR) << "Could not load CoreGraphics"; - return false; - } - - get_window_list_ = dlsym(lib_handle_, kWindowListCopyWindowInfo); - get_window_list_desc_ = - dlsym(lib_handle_, kWindowListCreateDescriptionFromArray); - if (get_window_list_ == NULL || get_window_list_desc_ == NULL) { - // The CGWindowListCopyWindowInfo and the - // CGWindowListCreateDescriptionFromArray functions was introduced - // in Leopard(10.5) so this is a normal failure on Tiger. - LOG(LS_INFO) << "Failed to load Core Graphics symbols"; - dlclose(lib_handle_); - lib_handle_ = NULL; - return false; - } - - return true; -} - -bool MacWindowPicker::IsVisible(const WindowId& id) { - // Init if we're not already inited. - if (get_window_list_desc_ == NULL && !Init()) { - return false; - } - CGWindowID ids[1]; - ids[0] = id.id(); - CFArrayRef window_id_array = - CFArrayCreate(NULL, reinterpret_cast(&ids), 1, NULL); - - CFArrayRef window_array = - reinterpret_cast( - get_window_list_desc_)(window_id_array); - if (window_array == NULL || 0 == CFArrayGetCount(window_array)) { - // Could not find the window. It might have been closed. - LOG(LS_INFO) << "Window not found"; - CFRelease(window_id_array); - return false; - } - - CFDictionaryRef window = reinterpret_cast( - CFArrayGetValueAtIndex(window_array, 0)); - CFBooleanRef is_visible = reinterpret_cast( - CFDictionaryGetValue(window, kCGWindowIsOnscreen)); - - // Check that the window is visible. If not we might crash. - bool visible = false; - if (is_visible != NULL) { - visible = CFBooleanGetValue(is_visible); - } - CFRelease(window_id_array); - CFRelease(window_array); - return visible; -} - -bool MacWindowPicker::MoveToFront(const WindowId& id) { - return false; -} - -bool MacWindowPicker::GetDesktopList(DesktopDescriptionList* descriptions) { - const uint32_t kMaxDisplays = 128; - CGDirectDisplayID active_displays[kMaxDisplays]; - uint32_t display_count = 0; - - CGError err = CGGetActiveDisplayList(kMaxDisplays, - active_displays, - &display_count); - if (err != kCGErrorSuccess) { - LOG_E(LS_ERROR, OS, err) << "Failed to enumerate the active displays."; - return false; - } - for (uint32_t i = 0; i < display_count; ++i) { - DesktopId id(active_displays[i], static_cast(i)); - // TODO: Figure out an appropriate desktop title. - DesktopDescription desc(id, ""); - desc.set_primary(CGDisplayIsMain(id.id())); - descriptions->push_back(desc); - } - return display_count > 0; -} - -bool MacWindowPicker::GetDesktopDimensions(const DesktopId& id, - int* width, - int* height) { - *width = CGDisplayPixelsWide(id.id()); - *height = CGDisplayPixelsHigh(id.id()); - return true; -} - -bool MacWindowPicker::GetWindowList(WindowDescriptionList* descriptions) { - // Init if we're not already inited. - if (get_window_list_ == NULL && !Init()) { - return false; - } - - // Only get onscreen, non-desktop windows. - CFArrayRef window_array = - reinterpret_cast(get_window_list_)( - kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, - kCGNullWindowID); - if (window_array == NULL) { - return false; - } - - // Check windows to make sure they have an id, title, and use window layer 0. - CFIndex i; - CFIndex count = CFArrayGetCount(window_array); - for (i = 0; i < count; ++i) { - CFDictionaryRef window = reinterpret_cast( - CFArrayGetValueAtIndex(window_array, i)); - CFStringRef window_title = reinterpret_cast( - CFDictionaryGetValue(window, kCGWindowName)); - CFNumberRef window_id = reinterpret_cast( - CFDictionaryGetValue(window, kCGWindowNumber)); - CFNumberRef window_layer = reinterpret_cast( - CFDictionaryGetValue(window, kCGWindowLayer)); - if (window_title != NULL && window_id != NULL && window_layer != NULL) { - std::string title_str; - int id_val, layer_val; - ToUtf8(window_title, &title_str); - CFNumberGetValue(window_id, kCFNumberIntType, &id_val); - CFNumberGetValue(window_layer, kCFNumberIntType, &layer_val); - - // Discard windows without a title. - if (layer_val == 0 && title_str.length() > 0) { - WindowId id(static_cast(id_val)); - WindowDescription desc(id, title_str); - descriptions->push_back(desc); - } - } - } - - CFRelease(window_array); - return true; -} - -} // namespace rtc diff --git a/webrtc/base/macwindowpicker.h b/webrtc/base/macwindowpicker.h deleted file mode 100644 index 99091a9893..0000000000 --- a/webrtc/base/macwindowpicker.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2010 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_BASE_MACWINDOWPICKER_H_ -#define WEBRTC_BASE_MACWINDOWPICKER_H_ - -#include "webrtc/base/windowpicker.h" - -namespace rtc { - -class MacWindowPicker : public WindowPicker { - public: - MacWindowPicker(); - ~MacWindowPicker() override; - bool Init() override; - bool IsVisible(const WindowId& id) override; - bool MoveToFront(const WindowId& id) override; - bool GetWindowList(WindowDescriptionList* descriptions) override; - bool GetDesktopList(DesktopDescriptionList* descriptions) override; - bool GetDesktopDimensions(const DesktopId& id, - int* width, - int* height) override; - - private: - void* lib_handle_; - void* get_window_list_; - void* get_window_list_desc_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_MACWINDOWPICKER_H_ diff --git a/webrtc/base/macwindowpicker_unittest.cc b/webrtc/base/macwindowpicker_unittest.cc deleted file mode 100644 index 7140f02313..0000000000 --- a/webrtc/base/macwindowpicker_unittest.cc +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2010 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/base/gunit.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/macutils.h" -#include "webrtc/base/macwindowpicker.h" -#include "webrtc/base/windowpicker.h" - -#if !defined(WEBRTC_MAC) || defined(WEBRTC_IOS) -#error Only for WEBRTC_MAC && !WEBRTC_IOS -#endif - -namespace rtc { - -bool IsLeopardOrLater() { - return GetOSVersionName() >= kMacOSLeopard; -} - -// Test that this works on new versions and fails acceptably on old versions. -TEST(MacWindowPickerTest, TestGetWindowList) { - MacWindowPicker picker, picker2; - WindowDescriptionList descriptions; - if (IsLeopardOrLater()) { - EXPECT_TRUE(picker.Init()); - EXPECT_TRUE(picker.GetWindowList(&descriptions)); - EXPECT_TRUE(picker2.GetWindowList(&descriptions)); // Init is optional - } else { - EXPECT_FALSE(picker.Init()); - EXPECT_FALSE(picker.GetWindowList(&descriptions)); - EXPECT_FALSE(picker2.GetWindowList(&descriptions)); - } -} - -// TODO: Add verification of the actual parsing, ie, add -// functionality to inject a fake get_window_array function which -// provide a pre-constructed list of windows. - -} // namespace rtc diff --git a/webrtc/base/win32windowpicker.cc b/webrtc/base/win32windowpicker.cc deleted file mode 100644 index da05a5c65c..0000000000 --- a/webrtc/base/win32windowpicker.cc +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2010 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/base/win32windowpicker.h" - -#include -#include - -#include "webrtc/base/arraysize.h" -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" - -namespace rtc { - -namespace { - -// Window class names that we want to filter out. -const char kProgramManagerClass[] = "Progman"; -const char kButtonClass[] = "Button"; - -} // namespace - -BOOL CALLBACK Win32WindowPicker::EnumProc(HWND hwnd, LPARAM l_param) { - WindowDescriptionList* descriptions = - reinterpret_cast(l_param); - - // Skip windows that are invisible, minimized, have no title, or are owned, - // unless they have the app window style set. Except for minimized windows, - // this is what Alt-Tab does. - // TODO: Figure out how to grab a thumbnail of a minimized window and - // include them in the list. - int len = GetWindowTextLength(hwnd); - HWND owner = GetWindow(hwnd, GW_OWNER); - LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); - if (len == 0 || IsIconic(hwnd) || !IsWindowVisible(hwnd) || - (owner && !(exstyle & WS_EX_APPWINDOW))) { - // TODO: Investigate if windows without title still could be - // interesting to share. We could use the name of the process as title: - // - // GetWindowThreadProcessId() - // OpenProcess() - // QueryFullProcessImageName() - return TRUE; - } - - // Skip the Program Manager window and the Start button. - TCHAR class_name_w[500]; - ::GetClassName(hwnd, class_name_w, 500); - std::string class_name = ToUtf8(class_name_w); - if (class_name == kProgramManagerClass || class_name == kButtonClass) { - // We don't want the Program Manager window nor the Start button. - return TRUE; - } - - TCHAR window_title[500]; - GetWindowText(hwnd, window_title, arraysize(window_title)); - std::string title = ToUtf8(window_title); - - WindowId id(hwnd); - WindowDescription desc(id, title); - descriptions->push_back(desc); - return TRUE; -} - -BOOL CALLBACK Win32WindowPicker::MonitorEnumProc(HMONITOR h_monitor, - HDC hdc_monitor, - LPRECT lprc_monitor, - LPARAM l_param) { - DesktopDescriptionList* desktop_desc = - reinterpret_cast(l_param); - - DesktopId id(h_monitor, static_cast(desktop_desc->size())); - // TODO: Figure out an appropriate desktop title. - DesktopDescription desc(id, ""); - - // Determine whether it's the primary monitor. - MONITORINFO monitor_info = {0}; - monitor_info.cbSize = sizeof(monitor_info); - bool primary = (GetMonitorInfo(h_monitor, &monitor_info) && - (monitor_info.dwFlags & MONITORINFOF_PRIMARY) != 0); - desc.set_primary(primary); - - desktop_desc->push_back(desc); - return TRUE; -} - -Win32WindowPicker::Win32WindowPicker() { -} - -bool Win32WindowPicker::Init() { - return true; -} -// TODO: Consider changing enumeration to clear() descriptions -// before append(). -bool Win32WindowPicker::GetWindowList(WindowDescriptionList* descriptions) { - LPARAM desc = reinterpret_cast(descriptions); - return EnumWindows(Win32WindowPicker::EnumProc, desc) != FALSE; -} - -bool Win32WindowPicker::GetDesktopList(DesktopDescriptionList* descriptions) { - // Create a fresh WindowDescriptionList so that we can use desktop_desc.size() - // in MonitorEnumProc to compute the desktop index. - DesktopDescriptionList desktop_desc; - HDC hdc = GetDC(NULL); - bool success = false; - if (EnumDisplayMonitors(hdc, NULL, Win32WindowPicker::MonitorEnumProc, - reinterpret_cast(&desktop_desc)) != FALSE) { - // Append the desktop descriptions to the end of the returned descriptions. - descriptions->insert(descriptions->end(), desktop_desc.begin(), - desktop_desc.end()); - success = true; - } - ReleaseDC(NULL, hdc); - return success; -} - -bool Win32WindowPicker::GetDesktopDimensions(const DesktopId& id, - int* width, - int* height) { - MONITORINFOEX monitor_info; - monitor_info.cbSize = sizeof(MONITORINFOEX); - if (!GetMonitorInfo(id.id(), &monitor_info)) { - return false; - } - *width = monitor_info.rcMonitor.right - monitor_info.rcMonitor.left; - *height = monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top; - return true; -} - -bool Win32WindowPicker::IsVisible(const WindowId& id) { - return (::IsWindow(id.id()) != FALSE && ::IsWindowVisible(id.id()) != FALSE); -} - -bool Win32WindowPicker::MoveToFront(const WindowId& id) { - return SetForegroundWindow(id.id()) != FALSE; -} - -} // namespace rtc diff --git a/webrtc/base/win32windowpicker.h b/webrtc/base/win32windowpicker.h deleted file mode 100644 index 9c84bfd987..0000000000 --- a/webrtc/base/win32windowpicker.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2010 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_BASE_WIN32WINDOWPICKER_H_ -#define WEBRTC_BASE_WIN32WINDOWPICKER_H_ - -#include "webrtc/base/win32.h" -#include "webrtc/base/windowpicker.h" - -namespace rtc { - -class Win32WindowPicker : public WindowPicker { - public: - Win32WindowPicker(); - virtual bool Init(); - virtual bool IsVisible(const WindowId& id); - virtual bool MoveToFront(const WindowId& id); - virtual bool GetWindowList(WindowDescriptionList* descriptions); - virtual bool GetDesktopList(DesktopDescriptionList* descriptions); - virtual bool GetDesktopDimensions(const DesktopId& id, int* width, - int* height); - - protected: - static BOOL CALLBACK EnumProc(HWND hwnd, LPARAM l_param); - static BOOL CALLBACK MonitorEnumProc(HMONITOR h_monitor, - HDC hdc_monitor, - LPRECT lprc_monitor, - LPARAM l_param); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_WIN32WINDOWPICKER_H_ diff --git a/webrtc/base/win32windowpicker_unittest.cc b/webrtc/base/win32windowpicker_unittest.cc deleted file mode 100644 index 701bb27d42..0000000000 --- a/webrtc/base/win32windowpicker_unittest.cc +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2010 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/base/arraysize.h" -#include "webrtc/base/gunit.h" -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/win32window.h" -#include "webrtc/base/win32windowpicker.h" -#include "webrtc/base/windowpicker.h" - -#if !defined(WEBRTC_WIN) -#error Only for Windows -#endif - -namespace rtc { - -static const TCHAR* kVisibleWindowTitle = L"Visible Window"; -static const TCHAR* kInvisibleWindowTitle = L"Invisible Window"; - -class Win32WindowPickerForTest : public Win32WindowPicker { - public: - Win32WindowPickerForTest() { - EXPECT_TRUE(visible_window_.Create(NULL, kVisibleWindowTitle, WS_VISIBLE, - 0, 0, 0, 0, 0)); - EXPECT_TRUE(invisible_window_.Create(NULL, kInvisibleWindowTitle, 0, - 0, 0, 0, 0, 0)); - } - - ~Win32WindowPickerForTest() { - visible_window_.Destroy(); - invisible_window_.Destroy(); - } - - virtual bool GetWindowList(WindowDescriptionList* descriptions) { - if (!Win32WindowPicker::EnumProc(visible_window_.handle(), - reinterpret_cast(descriptions))) { - return false; - } - if (!Win32WindowPicker::EnumProc(invisible_window_.handle(), - reinterpret_cast(descriptions))) { - return false; - } - return true; - } - - Win32Window* visible_window() { - return &visible_window_; - } - - Win32Window* invisible_window() { - return &invisible_window_; - } - - private: - Win32Window visible_window_; - Win32Window invisible_window_; -}; - -TEST(Win32WindowPickerTest, TestGetWindowList) { - Win32WindowPickerForTest window_picker; - WindowDescriptionList descriptions; - EXPECT_TRUE(window_picker.GetWindowList(&descriptions)); - EXPECT_EQ(1, descriptions.size()); - WindowDescription desc = descriptions.front(); - EXPECT_EQ(window_picker.visible_window()->handle(), desc.id().id()); - TCHAR window_title[500]; - GetWindowText(window_picker.visible_window()->handle(), window_title, - arraysize(window_title)); - EXPECT_EQ(0, wcscmp(window_title, kVisibleWindowTitle)); -} - -TEST(Win32WindowPickerTest, TestIsVisible) { - Win32WindowPickerForTest window_picker; - HWND visible_id = window_picker.visible_window()->handle(); - HWND invisible_id = window_picker.invisible_window()->handle(); - EXPECT_TRUE(window_picker.IsVisible(WindowId(visible_id))); - EXPECT_FALSE(window_picker.IsVisible(WindowId(invisible_id))); -} - -TEST(Win32WindowPickerTest, TestMoveToFront) { - Win32WindowPickerForTest window_picker; - HWND visible_id = window_picker.visible_window()->handle(); - HWND invisible_id = window_picker.invisible_window()->handle(); - - // There are a number of condition where SetForegroundWindow might - // fail depending on the state of the calling process. To be on the - // safe side we doesn't expect MoveToFront to return true, just test - // that we don't crash. - window_picker.MoveToFront(WindowId(visible_id)); - window_picker.MoveToFront(WindowId(invisible_id)); -} - -} // namespace rtc diff --git a/webrtc/base/windowpicker.h b/webrtc/base/windowpicker.h deleted file mode 100644 index 3ae7b0e491..0000000000 --- a/webrtc/base/windowpicker.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2010 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_BASE_WINDOWPICKER_H_ -#define WEBRTC_BASE_WINDOWPICKER_H_ - -#include -#include - -#include "webrtc/base/window.h" - -namespace rtc { - -class WindowDescription { - public: - WindowDescription() : id_() {} - WindowDescription(const WindowId& id, const std::string& title) - : id_(id), title_(title) { - } - const WindowId& id() const { return id_; } - void set_id(const WindowId& id) { id_ = id; } - const std::string& title() const { return title_; } - void set_title(const std::string& title) { title_ = title; } - - private: - WindowId id_; - std::string title_; -}; - -class DesktopDescription { - public: - DesktopDescription() : id_() {} - DesktopDescription(const DesktopId& id, const std::string& title) - : id_(id), title_(title), primary_(false) { - } - const DesktopId& id() const { return id_; } - void set_id(const DesktopId& id) { id_ = id; } - const std::string& title() const { return title_; } - void set_title(const std::string& title) { title_ = title; } - // Indicates whether it is the primary desktop in the system. - bool primary() const { return primary_; } - void set_primary(bool primary) { primary_ = primary; } - - private: - DesktopId id_; - std::string title_; - bool primary_; -}; - -typedef std::vector WindowDescriptionList; -typedef std::vector DesktopDescriptionList; - -class WindowPicker { - public: - virtual ~WindowPicker() {} - virtual bool Init() = 0; - - // TODO: Move this two methods to window.h when we no longer need to load - // CoreGraphics dynamically. - virtual bool IsVisible(const WindowId& id) = 0; - virtual bool MoveToFront(const WindowId& id) = 0; - - // Gets a list of window description and appends to descriptions. - // Returns true if successful. - virtual bool GetWindowList(WindowDescriptionList* descriptions) = 0; - // Gets a list of desktop descriptions and appends to descriptions. - // Returns true if successful. - virtual bool GetDesktopList(DesktopDescriptionList* descriptions) = 0; - // Gets the width and height of a desktop. - // Returns true if successful. - virtual bool GetDesktopDimensions(const DesktopId& id, int* width, - int* height) = 0; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_WINDOWPICKER_H_ diff --git a/webrtc/base/windowpicker_unittest.cc b/webrtc/base/windowpicker_unittest.cc deleted file mode 100644 index a125832708..0000000000 --- a/webrtc/base/windowpicker_unittest.cc +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2012 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/base/gunit.h" -#include "webrtc/base/testutils.h" -#include "webrtc/base/window.h" -#include "webrtc/base/windowpicker.h" -#include "webrtc/base/windowpickerfactory.h" - -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -# define DISABLE_ON_MAC(name) DISABLED_ ## name -#else -# define DISABLE_ON_MAC(name) name -#endif - -TEST(WindowPickerTest, GetWindowList) { - MAYBE_SKIP_SCREENCAST_TEST(); - if (!rtc::WindowPickerFactory::IsSupported()) { - LOG(LS_INFO) << "skipping test: window capturing is not supported with " - << "current configuration."; - } - std::unique_ptr picker( - rtc::WindowPickerFactory::CreateWindowPicker()); - EXPECT_TRUE(picker->Init()); - rtc::WindowDescriptionList descriptions; - EXPECT_TRUE(picker->GetWindowList(&descriptions)); -} - -// TODO(hughv) Investigate why this fails on pulse but not locally after -// upgrading to XCode 4.5. The failure is GetDesktopList returning FALSE. -TEST(WindowPickerTest, DISABLE_ON_MAC(GetDesktopList)) { - MAYBE_SKIP_SCREENCAST_TEST(); - if (!rtc::WindowPickerFactory::IsSupported()) { - LOG(LS_INFO) << "skipping test: window capturing is not supported with " - << "current configuration."; - } - std::unique_ptr picker( - rtc::WindowPickerFactory::CreateWindowPicker()); - EXPECT_TRUE(picker->Init()); - rtc::DesktopDescriptionList descriptions; - EXPECT_TRUE(picker->GetDesktopList(&descriptions)); - if (descriptions.size() > 0) { - int width = 0; - int height = 0; - EXPECT_TRUE(picker->GetDesktopDimensions(descriptions[0].id(), &width, - &height)); - EXPECT_GT(width, 0); - EXPECT_GT(height, 0); - - // Test |IsPrimaryDesktop|. Only one desktop should be a primary. - bool found_primary = false; - for (rtc::DesktopDescriptionList::iterator it = descriptions.begin(); - it != descriptions.end(); ++it) { - if (it->primary()) { - EXPECT_FALSE(found_primary); - found_primary = true; - } - } - EXPECT_TRUE(found_primary); - } -} diff --git a/webrtc/base/windowpickerfactory.h b/webrtc/base/windowpickerfactory.h deleted file mode 100644 index dec3a33013..0000000000 --- a/webrtc/base/windowpickerfactory.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2010 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_BASE_WINDOWPICKERFACTORY_H_ -#define WEBRTC_BASE_WINDOWPICKERFACTORY_H_ - -#if defined(WEBRTC_WIN) -#include "webrtc/base/win32windowpicker.h" -#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) -#include "webrtc/base/macutils.h" -#include "webrtc/base/macwindowpicker.h" -#elif defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) && defined(HAVE_X11) -#include "webrtc/base/x11windowpicker.h" -#endif - -#include "webrtc/base/windowpicker.h" - -namespace rtc { - -class WindowPickerFactory { - public: - virtual ~WindowPickerFactory() {} - - // Instance method for dependency injection. - virtual WindowPicker* Create() { - return CreateWindowPicker(); - } - - static WindowPicker* CreateWindowPicker() { -#if defined(WEBRTC_WIN) - return new Win32WindowPicker(); -#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - return new MacWindowPicker(); -#elif defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) && defined(HAVE_X11) - return new X11WindowPicker(); -#else - return NULL; -#endif - } - - static bool IsSupported() { -#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - return GetOSVersionName() >= kMacOSLeopard; -#else - return true; -#endif - } -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_WINDOWPICKERFACTORY_H_ diff --git a/webrtc/base/x11windowpicker.cc b/webrtc/base/x11windowpicker.cc deleted file mode 100644 index e588304d03..0000000000 --- a/webrtc/base/x11windowpicker.cc +++ /dev/null @@ -1,816 +0,0 @@ -/* - * Copyright 2010 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/base/x11windowpicker.h" - -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include "webrtc/base/constructormagic.h" -#include "webrtc/base/logging.h" - -namespace rtc { - -// Convenience wrapper for XGetWindowProperty results. -template -class XWindowProperty { - public: - XWindowProperty(Display* display, Window window, Atom property) - : data_(NULL) { - const int kBitsPerByte = 8; - Atom actual_type; - int actual_format; - unsigned long bytes_after; // NOLINT: type required by XGetWindowProperty - int status = XGetWindowProperty(display, window, property, 0L, ~0L, False, - AnyPropertyType, &actual_type, - &actual_format, &size_, - &bytes_after, &data_); - succeeded_ = (status == Success); - if (!succeeded_) { - data_ = NULL; // Ensure nothing is freed. - } else if (sizeof(PropertyType) * kBitsPerByte != actual_format) { - LOG(LS_WARNING) << "Returned type size differs from " - "requested type size."; - succeeded_ = false; - // We still need to call XFree in this case, so leave data_ alone. - } - if (!succeeded_) { - size_ = 0; - } - } - - ~XWindowProperty() { - if (data_) { - XFree(data_); - } - } - - bool succeeded() const { return succeeded_; } - size_t size() const { return size_; } - const PropertyType* data() const { - return reinterpret_cast(data_); - } - PropertyType* data() { - return reinterpret_cast(data_); - } - - private: - bool succeeded_; - unsigned long size_; // NOLINT: type required by XGetWindowProperty - unsigned char* data_; - - RTC_DISALLOW_COPY_AND_ASSIGN(XWindowProperty); -}; - -// Stupid X11. It seems none of the synchronous returns codes from X11 calls -// are meaningful unless an asynchronous error handler is configured. This -// RAII class registers and unregisters an X11 error handler. -class XErrorSuppressor { - public: - explicit XErrorSuppressor(Display* display) - : display_(display), original_error_handler_(NULL) { - SuppressX11Errors(); - } - ~XErrorSuppressor() { - UnsuppressX11Errors(); - } - - private: - static int ErrorHandler(Display* display, XErrorEvent* e) { - char buf[256]; - XGetErrorText(display, e->error_code, buf, sizeof buf); - LOG(LS_WARNING) << "Received X11 error \"" << buf << "\" for request code " - << static_cast(e->request_code); - return 0; - } - - void SuppressX11Errors() { - XFlush(display_); - XSync(display_, False); - original_error_handler_ = XSetErrorHandler(&ErrorHandler); - } - - void UnsuppressX11Errors() { - XFlush(display_); - XSync(display_, False); - XErrorHandler handler = XSetErrorHandler(original_error_handler_); - if (handler != &ErrorHandler) { - LOG(LS_WARNING) << "Unbalanced XSetErrorHandler() calls detected. " - << "Final error handler may not be what you expect!"; - } - original_error_handler_ = NULL; - } - - Display* display_; - XErrorHandler original_error_handler_; - - RTC_DISALLOW_COPY_AND_ASSIGN(XErrorSuppressor); -}; - -// Hiding all X11 specifics inside its own class. This to avoid -// conflicts between talk and X11 header declarations. -class XWindowEnumerator { - public: - XWindowEnumerator() - : display_(NULL), - has_composite_extension_(false), - has_render_extension_(false) { - } - - ~XWindowEnumerator() { - if (display_ != NULL) { - XCloseDisplay(display_); - } - } - - bool Init() { - if (display_ != NULL) { - // Already initialized. - return true; - } - display_ = XOpenDisplay(NULL); - if (display_ == NULL) { - LOG(LS_ERROR) << "Failed to open display."; - return false; - } - - XErrorSuppressor error_suppressor(display_); - - wm_state_ = XInternAtom(display_, "WM_STATE", True); - net_wm_icon_ = XInternAtom(display_, "_NET_WM_ICON", False); - - int event_base, error_base, major_version, minor_version; - if (XCompositeQueryExtension(display_, &event_base, &error_base) && - XCompositeQueryVersion(display_, &major_version, &minor_version) && - // XCompositeNameWindowPixmap() requires version 0.2 - (major_version > 0 || minor_version >= 2)) { - has_composite_extension_ = true; - } else { - LOG(LS_INFO) << "Xcomposite extension not available or too old."; - } - - if (XRenderQueryExtension(display_, &event_base, &error_base) && - XRenderQueryVersion(display_, &major_version, &minor_version) && - // XRenderSetPictureTransform() requires version 0.6 - (major_version > 0 || minor_version >= 6)) { - has_render_extension_ = true; - } else { - LOG(LS_INFO) << "Xrender extension not available or too old."; - } - return true; - } - - bool EnumerateWindows(WindowDescriptionList* descriptions) { - if (!Init()) { - return false; - } - XErrorSuppressor error_suppressor(display_); - int num_screens = XScreenCount(display_); - bool result = false; - for (int i = 0; i < num_screens; ++i) { - if (EnumerateScreenWindows(descriptions, i)) { - // We know we succeded on at least one screen. - result = true; - } - } - return result; - } - - bool EnumerateDesktops(DesktopDescriptionList* descriptions) { - if (!Init()) { - return false; - } - XErrorSuppressor error_suppressor(display_); - Window default_root_window = XDefaultRootWindow(display_); - int num_screens = XScreenCount(display_); - for (int i = 0; i < num_screens; ++i) { - Window root_window = XRootWindow(display_, i); - DesktopId id(DesktopId(root_window, i)); - // TODO: Figure out an appropriate desktop title. - DesktopDescription desc(id, ""); - desc.set_primary(root_window == default_root_window); - descriptions->push_back(desc); - } - return num_screens > 0; - } - - bool IsVisible(const WindowId& id) { - if (!Init()) { - return false; - } - XErrorSuppressor error_suppressor(display_); - XWindowAttributes attr; - if (!XGetWindowAttributes(display_, id.id(), &attr)) { - LOG(LS_ERROR) << "XGetWindowAttributes() failed"; - return false; - } - return attr.map_state == IsViewable; - } - - bool MoveToFront(const WindowId& id) { - if (!Init()) { - return false; - } - XErrorSuppressor error_suppressor(display_); - unsigned int num_children; - Window* children; - Window parent; - Window root; - - // Find root window to pass event to. - int status = XQueryTree(display_, id.id(), &root, &parent, &children, - &num_children); - if (status == 0) { - LOG(LS_WARNING) << "Failed to query for child windows."; - return false; - } - if (children != NULL) { - XFree(children); - } - - // Move the window to front. - XRaiseWindow(display_, id.id()); - - // Some window managers (e.g., metacity in GNOME) consider it illegal to - // raise a window without also giving it input focus with - // _NET_ACTIVE_WINDOW, so XRaiseWindow() on its own isn't enough. - Atom atom = XInternAtom(display_, "_NET_ACTIVE_WINDOW", True); - if (atom != None) { - XEvent xev; - long event_mask; - - xev.xclient.type = ClientMessage; - xev.xclient.serial = 0; - xev.xclient.send_event = True; - xev.xclient.window = id.id(); - xev.xclient.message_type = atom; - - // The format member is set to 8, 16, or 32 and specifies whether the - // data should be viewed as a list of bytes, shorts, or longs. - xev.xclient.format = 32; - - xev.xclient.data.l[0] = 0; - xev.xclient.data.l[1] = 0; - xev.xclient.data.l[2] = 0; - xev.xclient.data.l[3] = 0; - xev.xclient.data.l[4] = 0; - - event_mask = SubstructureRedirectMask | SubstructureNotifyMask; - - XSendEvent(display_, root, False, event_mask, &xev); - } - XFlush(display_); - return true; - } - - uint8_t* GetWindowIcon(const WindowId& id, int* width, int* height) { - if (!Init()) { - return NULL; - } - XErrorSuppressor error_suppressor(display_); - Atom ret_type; - int format; - unsigned long length, bytes_after, size; - unsigned char* data = NULL; - - // Find out the size of the icon data. - if (XGetWindowProperty( - display_, id.id(), net_wm_icon_, 0, 0, False, XA_CARDINAL, - &ret_type, &format, &length, &size, &data) == Success && - data) { - XFree(data); - } else { - LOG(LS_ERROR) << "Failed to get size of the icon."; - return NULL; - } - // Get the icon data, the format is one uint32_t each for width and height, - // followed by the actual pixel data. - if (size >= 2 && - XGetWindowProperty( - display_, id.id(), net_wm_icon_, 0, size, False, XA_CARDINAL, - &ret_type, &format, &length, &bytes_after, &data) == Success && - data) { - uint32_t* data_ptr = reinterpret_cast(data); - int w, h; - w = data_ptr[0]; - h = data_ptr[1]; - if (size < static_cast(w * h + 2)) { - XFree(data); - LOG(LS_ERROR) << "Not a vaild icon."; - return NULL; - } - uint8_t* rgba = ArgbToRgba(&data_ptr[2], 0, 0, w, h, w, h, true); - XFree(data); - *width = w; - *height = h; - return rgba; - } else { - LOG(LS_ERROR) << "Failed to get window icon data."; - return NULL; - } - } - - uint8_t* GetWindowThumbnail(const WindowId& id, int width, int height) { - if (!Init()) { - return NULL; - } - - if (!has_composite_extension_) { - // Without the Xcomposite extension we would only get a good thumbnail if - // the whole window is visible on screen and not covered by any - // other window. This is not something we want so instead, just - // bail out. - LOG(LS_INFO) << "No Xcomposite extension detected."; - return NULL; - } - XErrorSuppressor error_suppressor(display_); - - Window root; - int x; - int y; - unsigned int src_width; - unsigned int src_height; - unsigned int border_width; - unsigned int depth; - - // In addition to needing X11 server-side support for Xcomposite, it - // actually needs to be turned on for this window in order to get a good - // thumbnail. If the user has modern hardware/drivers but isn't using a - // compositing window manager, that won't be the case. Here we - // automatically turn it on for shareable windows so that we can get - // thumbnails. We used to avoid it because the transition is visually ugly, - // but recent window managers don't always redirect windows which led to - // no thumbnails at all, which is a worse experience. - - // Redirect drawing to an offscreen buffer (ie, turn on compositing). - // X11 remembers what has requested this and will turn it off for us when - // we exit. - XCompositeRedirectWindow(display_, id.id(), CompositeRedirectAutomatic); - Pixmap src_pixmap = XCompositeNameWindowPixmap(display_, id.id()); - if (!src_pixmap) { - // Even if the backing pixmap doesn't exist, this still should have - // succeeded and returned a valid handle (it just wouldn't be a handle to - // anything). So this is a real error path. - LOG(LS_ERROR) << "XCompositeNameWindowPixmap() failed"; - return NULL; - } - if (!XGetGeometry(display_, src_pixmap, &root, &x, &y, - &src_width, &src_height, &border_width, - &depth)) { - // If the window does not actually have a backing pixmap, this is the path - // that will "fail", so it's a warning rather than an error. - LOG(LS_WARNING) << "XGetGeometry() failed (probably composite is not in " - << "use)"; - XFreePixmap(display_, src_pixmap); - return NULL; - } - - // If we get to here, then composite is in use for this window and it has a - // valid backing pixmap. - - XWindowAttributes attr; - if (!XGetWindowAttributes(display_, id.id(), &attr)) { - LOG(LS_ERROR) << "XGetWindowAttributes() failed"; - XFreePixmap(display_, src_pixmap); - return NULL; - } - - uint8_t* data = GetDrawableThumbnail(src_pixmap, attr.visual, src_width, - src_height, width, height); - XFreePixmap(display_, src_pixmap); - return data; - } - - int GetNumDesktops() { - if (!Init()) { - return -1; - } - - return XScreenCount(display_); - } - - uint8_t* GetDesktopThumbnail(const DesktopId& id, int width, int height) { - if (!Init()) { - return NULL; - } - XErrorSuppressor error_suppressor(display_); - - Window root_window = id.id(); - XWindowAttributes attr; - if (!XGetWindowAttributes(display_, root_window, &attr)) { - LOG(LS_ERROR) << "XGetWindowAttributes() failed"; - return NULL; - } - - return GetDrawableThumbnail(root_window, - attr.visual, - attr.width, - attr.height, - width, - height); - } - - bool GetDesktopDimensions(const DesktopId& id, int* width, int* height) { - if (!Init()) { - return false; - } - XErrorSuppressor error_suppressor(display_); - XWindowAttributes attr; - if (!XGetWindowAttributes(display_, id.id(), &attr)) { - LOG(LS_ERROR) << "XGetWindowAttributes() failed"; - return false; - } - *width = attr.width; - *height = attr.height; - return true; - } - - private: - uint8_t* GetDrawableThumbnail(Drawable src_drawable, - Visual* visual, - int src_width, - int src_height, - int dst_width, - int dst_height) { - if (!has_render_extension_) { - // Without the Xrender extension we would have to read the full window and - // scale it down in our process. Xrender is over a decade old so we aren't - // going to expend effort to support that situation. We still need to - // check though because probably some virtual VNC displays are in this - // category. - LOG(LS_INFO) << "No Xrender extension detected."; - return NULL; - } - - XRenderPictFormat* format = XRenderFindVisualFormat(display_, - visual); - if (!format) { - LOG(LS_ERROR) << "XRenderFindVisualFormat() failed"; - return NULL; - } - - // Create a picture to reference the window pixmap. - XRenderPictureAttributes pa; - pa.subwindow_mode = IncludeInferiors; // Don't clip child widgets - Picture src = XRenderCreatePicture(display_, - src_drawable, - format, - CPSubwindowMode, - &pa); - if (!src) { - LOG(LS_ERROR) << "XRenderCreatePicture() failed"; - return NULL; - } - - // Create a picture to reference the destination pixmap. - Pixmap dst_pixmap = XCreatePixmap(display_, - src_drawable, - dst_width, - dst_height, - format->depth); - if (!dst_pixmap) { - LOG(LS_ERROR) << "XCreatePixmap() failed"; - XRenderFreePicture(display_, src); - return NULL; - } - - Picture dst = XRenderCreatePicture(display_, dst_pixmap, format, 0, NULL); - if (!dst) { - LOG(LS_ERROR) << "XRenderCreatePicture() failed"; - XFreePixmap(display_, dst_pixmap); - XRenderFreePicture(display_, src); - return NULL; - } - - // Clear the background. - XRenderColor transparent = {0}; - XRenderFillRectangle(display_, - PictOpSrc, - dst, - &transparent, - 0, - 0, - dst_width, - dst_height); - - // Calculate how much we need to scale the image. - double scale_x = static_cast(dst_width) / - static_cast(src_width); - double scale_y = static_cast(dst_height) / - static_cast(src_height); - double scale = std::min(scale_y, scale_x); - - int scaled_width = round(src_width * scale); - int scaled_height = round(src_height * scale); - - // Render the thumbnail centered on both axis. - int centered_x = (dst_width - scaled_width) / 2; - int centered_y = (dst_height - scaled_height) / 2; - - // Scaling matrix - XTransform xform = { { - { XDoubleToFixed(1), XDoubleToFixed(0), XDoubleToFixed(0) }, - { XDoubleToFixed(0), XDoubleToFixed(1), XDoubleToFixed(0) }, - { XDoubleToFixed(0), XDoubleToFixed(0), XDoubleToFixed(scale) } - } }; - XRenderSetPictureTransform(display_, src, &xform); - - // Apply filter to smooth out the image. - XRenderSetPictureFilter(display_, src, FilterBest, NULL, 0); - - // Render the image to the destination picture. - XRenderComposite(display_, - PictOpSrc, - src, - None, - dst, - 0, - 0, - 0, - 0, - centered_x, - centered_y, - scaled_width, - scaled_height); - - // Get the pixel data from the X server. TODO: XGetImage - // might be slow here, compare with ShmGetImage. - XImage* image = XGetImage(display_, - dst_pixmap, - 0, - 0, - dst_width, - dst_height, - AllPlanes, ZPixmap); - uint8_t* data = ArgbToRgba(reinterpret_cast(image->data), - centered_x, centered_y, scaled_width, - scaled_height, dst_width, dst_height, false); - XDestroyImage(image); - XRenderFreePicture(display_, dst); - XFreePixmap(display_, dst_pixmap); - XRenderFreePicture(display_, src); - return data; - } - - uint8_t* ArgbToRgba(uint32_t* argb_data, - int x, - int y, - int w, - int h, - int stride_x, - int stride_y, - bool has_alpha) { - uint8_t* p; - int len = stride_x * stride_y * 4; - uint8_t* data = new uint8_t[len]; - memset(data, 0, len); - p = data + 4 * (y * stride_x + x); - for (int i = 0; i < h; ++i) { - for (int j = 0; j < w; ++j) { - uint32_t argb; - uint32_t rgba; - argb = argb_data[stride_x * (y + i) + x + j]; - rgba = (argb << 8) | (argb >> 24); - *p = rgba >> 24; - ++p; - *p = (rgba >> 16) & 0xff; - ++p; - *p = (rgba >> 8) & 0xff; - ++p; - *p = has_alpha ? rgba & 0xFF : 0xFF; - ++p; - } - p += (stride_x - w) * 4; - } - return data; - } - - bool EnumerateScreenWindows(WindowDescriptionList* descriptions, int screen) { - Window parent; - Window *children; - int status; - unsigned int num_children; - Window root_window = XRootWindow(display_, screen); - status = XQueryTree(display_, root_window, &root_window, &parent, &children, - &num_children); - if (status == 0) { - LOG(LS_ERROR) << "Failed to query for child windows."; - return false; - } - for (unsigned int i = 0; i < num_children; ++i) { - // Iterate in reverse order to display windows from front to back. -#ifdef CHROMEOS - // TODO(jhorwich): Short-term fix for crbug.com/120229: Don't need to - // filter, just return all windows and let the picker scan through them. - Window app_window = children[num_children - 1 - i]; -#else - Window app_window = GetApplicationWindow(children[num_children - 1 - i]); -#endif - if (app_window && - !X11WindowPicker::IsDesktopElement(display_, app_window)) { - std::string title; - if (GetWindowTitle(app_window, &title)) { - WindowId id(app_window); - WindowDescription desc(id, title); - descriptions->push_back(desc); - } - } - } - if (children != NULL) { - XFree(children); - } - return true; - } - - bool GetWindowTitle(Window window, std::string* title) { - int status; - bool result = false; - XTextProperty window_name; - window_name.value = NULL; - if (window) { - status = XGetWMName(display_, window, &window_name); - if (status && window_name.value && window_name.nitems) { - int cnt; - char **list = NULL; - status = Xutf8TextPropertyToTextList(display_, &window_name, &list, - &cnt); - if (status >= Success && cnt && *list) { - if (cnt > 1) { - LOG(LS_INFO) << "Window has " << cnt - << " text properties, only using the first one."; - } - *title = *list; - result = true; - } - if (list != NULL) { - XFreeStringList(list); - } - } - if (window_name.value != NULL) { - XFree(window_name.value); - } - } - return result; - } - - Window GetApplicationWindow(Window window) { - Window root, parent; - Window app_window = 0; - Window *children; - unsigned int num_children; - Atom type = None; - int format; - unsigned long nitems, after; - unsigned char *data; - - int ret = XGetWindowProperty(display_, window, - wm_state_, 0L, 2, - False, wm_state_, &type, &format, - &nitems, &after, &data); - if (ret != Success) { - LOG(LS_ERROR) << "XGetWindowProperty failed with return code " << ret - << " for window " << window << "."; - return 0; - } - if (type != None) { - int64_t state = static_cast(*data); - XFree(data); - return state == NormalState ? window : 0; - } - XFree(data); - if (!XQueryTree(display_, window, &root, &parent, &children, - &num_children)) { - LOG(LS_ERROR) << "Failed to query for child windows although window" - << "does not have a valid WM_STATE."; - return 0; - } - for (unsigned int i = 0; i < num_children; ++i) { - app_window = GetApplicationWindow(children[i]); - if (app_window) { - break; - } - } - if (children != NULL) { - XFree(children); - } - return app_window; - } - - Atom wm_state_; - Atom net_wm_icon_; - Display* display_; - bool has_composite_extension_; - bool has_render_extension_; -}; - -X11WindowPicker::X11WindowPicker() : enumerator_(new XWindowEnumerator()) { -} - -X11WindowPicker::~X11WindowPicker() { -} - -bool X11WindowPicker::IsDesktopElement(_XDisplay* display, Window window) { - if (window == 0) { - LOG(LS_WARNING) << "Zero is never a valid window."; - return false; - } - - // First look for _NET_WM_WINDOW_TYPE. The standard - // (http://standards.freedesktop.org/wm-spec/latest/ar01s05.html#id2760306) - // says this hint *should* be present on all windows, and we use the existence - // of _NET_WM_WINDOW_TYPE_NORMAL in the property to indicate a window is not - // a desktop element (that is, only "normal" windows should be shareable). - Atom window_type_atom = XInternAtom(display, "_NET_WM_WINDOW_TYPE", True); - XWindowProperty window_type(display, window, window_type_atom); - if (window_type.succeeded() && window_type.size() > 0) { - Atom normal_window_type_atom = XInternAtom( - display, "_NET_WM_WINDOW_TYPE_NORMAL", True); - uint32_t* end = window_type.data() + window_type.size(); - bool is_normal = (end != std::find( - window_type.data(), end, normal_window_type_atom)); - return !is_normal; - } - - // Fall back on using the hint. - XClassHint class_hint; - Status s = XGetClassHint(display, window, &class_hint); - bool result = false; - if (s == 0) { - // No hints, assume this is a normal application window. - return result; - } - static const std::string gnome_panel("gnome-panel"); - static const std::string desktop_window("desktop_window"); - - if (gnome_panel.compare(class_hint.res_name) == 0 || - desktop_window.compare(class_hint.res_name) == 0) { - result = true; - } - XFree(class_hint.res_name); - XFree(class_hint.res_class); - return result; -} - -bool X11WindowPicker::Init() { - return enumerator_->Init(); -} - -bool X11WindowPicker::GetWindowList(WindowDescriptionList* descriptions) { - return enumerator_->EnumerateWindows(descriptions); -} - -bool X11WindowPicker::GetDesktopList(DesktopDescriptionList* descriptions) { - return enumerator_->EnumerateDesktops(descriptions); -} - -bool X11WindowPicker::IsVisible(const WindowId& id) { - return enumerator_->IsVisible(id); -} - -bool X11WindowPicker::MoveToFront(const WindowId& id) { - return enumerator_->MoveToFront(id); -} - -uint8_t* X11WindowPicker::GetWindowIcon(const WindowId& id, - int* width, - int* height) { - return enumerator_->GetWindowIcon(id, width, height); -} - -uint8_t* X11WindowPicker::GetWindowThumbnail(const WindowId& id, - int width, - int height) { - return enumerator_->GetWindowThumbnail(id, width, height); -} - -int X11WindowPicker::GetNumDesktops() { - return enumerator_->GetNumDesktops(); -} - -uint8_t* X11WindowPicker::GetDesktopThumbnail(const DesktopId& id, - int width, - int height) { - return enumerator_->GetDesktopThumbnail(id, width, height); -} - -bool X11WindowPicker::GetDesktopDimensions(const DesktopId& id, int* width, - int* height) { - return enumerator_->GetDesktopDimensions(id, width, height); -} - -} // namespace rtc diff --git a/webrtc/base/x11windowpicker.h b/webrtc/base/x11windowpicker.h deleted file mode 100644 index d741759368..0000000000 --- a/webrtc/base/x11windowpicker.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2010 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_BASE_LINUXWINDOWPICKER_H_ -#define WEBRTC_BASE_LINUXWINDOWPICKER_H_ - -#include - -#include "webrtc/base/basictypes.h" -#include "webrtc/base/windowpicker.h" - -// Avoid include . -struct _XDisplay; -typedef unsigned long Window; - -namespace rtc { - -class XWindowEnumerator; - -class X11WindowPicker : public WindowPicker { - public: - X11WindowPicker(); - ~X11WindowPicker() override; - - static bool IsDesktopElement(_XDisplay* display, Window window); - - bool Init() override; - bool IsVisible(const WindowId& id) override; - bool MoveToFront(const WindowId& id) override; - bool GetWindowList(WindowDescriptionList* descriptions) override; - bool GetDesktopList(DesktopDescriptionList* descriptions) override; - bool GetDesktopDimensions(const DesktopId& id, - int* width, - int* height) override; - uint8_t* GetWindowIcon(const WindowId& id, int* width, int* height); - uint8_t* GetWindowThumbnail(const WindowId& id, int width, int height); - int GetNumDesktops(); - uint8_t* GetDesktopThumbnail(const DesktopId& id, int width, int height); - - private: - std::unique_ptr enumerator_; -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_LINUXWINDOWPICKER_H_ diff --git a/webrtc/base/x11windowpicker_unittest.cc b/webrtc/base/x11windowpicker_unittest.cc deleted file mode 100644 index 482ac89aad..0000000000 --- a/webrtc/base/x11windowpicker_unittest.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2010 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/base/gunit.h" -#include "webrtc/base/x11windowpicker.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/testutils.h" -#include "webrtc/base/windowpicker.h" - -#if !defined(WEBRTC_LINUX) || defined(WEBRTC_ANDROID) -#error Only for Linux -#endif - -namespace rtc { - -TEST(X11WindowPickerTest, TestGetWindowList) { - MAYBE_SKIP_SCREENCAST_TEST(); - X11WindowPicker window_picker; - WindowDescriptionList descriptions; - window_picker.Init(); - window_picker.GetWindowList(&descriptions); -} - -TEST(X11WindowPickerTest, TestGetDesktopList) { - MAYBE_SKIP_SCREENCAST_TEST(); - X11WindowPicker window_picker; - DesktopDescriptionList descriptions; - EXPECT_TRUE(window_picker.Init()); - EXPECT_TRUE(window_picker.GetDesktopList(&descriptions)); - EXPECT_TRUE(descriptions.size() > 0); -} - -} // namespace rtc