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

Unified Diff: webrtc/modules/desktop_capture/window_capturer_x11.cc

Issue 2202883003: Icon Capture For Window Capturer (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fix windows crash Created 4 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/desktop_capture/window_capturer_x11.cc
diff --git a/webrtc/modules/desktop_capture/window_capturer_x11.cc b/webrtc/modules/desktop_capture/window_capturer_x11.cc
index d88585bfa8052d34a0de60b58a8089d6a3992bca..0d9fcef9853c7cd4b1b769355b697105634979bb 100644
--- a/webrtc/modules/desktop_capture/window_capturer_x11.cc
+++ b/webrtc/modules/desktop_capture/window_capturer_x11.cc
@@ -31,6 +31,36 @@
namespace webrtc {
namespace {
+const uint32_t kAlphaMask = 0xFF000000;
+const uint32_t kRedMask = 0x00FF0000;
+const uint32_t kGreenMask = 0x0000FF00;
+const uint32_t kBlueMask = 0x000000FF;
+
+const int kAlphaShift = 24;
+const int kRedShift = 16;
+const int kGreenShift = 8;
+const int kBlueShift = 0;
+
+uint32_t MultiplyAlpha(uint32_t raw_color_component, uint32_t alpha) {
+ uint32_t product = raw_color_component * alpha + 128;
+ return (product + (product >> 8)) >> 8;
+}
+
+// Convert a raw ARGB color pixel into a premultiplied ARGB color
+uint32_t PremultipliedColor(uint32_t raw_color) {
+ uint32_t alpha, red, green, blue;
+ alpha = (raw_color & kAlphaMask) >> kAlphaShift;
+ red = (raw_color & kRedMask) >> kRedShift;
+ green = (raw_color & kGreenMask) >> kGreenShift;
+ blue = (raw_color & kBlueMask) >> kBlueShift;
+
+ red = MultiplyAlpha(red, alpha);
+ green = MultiplyAlpha(green, alpha);
+ blue = MultiplyAlpha(blue, alpha);
+
+ return (alpha << kAlphaShift) | (red << kRedShift) | (green << kGreenShift) |
+ (blue << kBlueShift);
+}
// Convenience wrapper for XGetWindowProperty() results.
template <class PropertyType>
@@ -114,6 +144,8 @@ class WindowCapturerLinux : public WindowCapturer,
// Returns window title for the specified X |window|.
bool GetWindowTitle(::Window window, std::string* title);
+ std::unique_ptr<DesktopFrame> GetWindowIcon(::Window window);
+
Callback* callback_ = nullptr;
rtc::scoped_refptr<SharedXDisplay> x_display_;
@@ -121,6 +153,7 @@ class WindowCapturerLinux : public WindowCapturer,
Atom wm_state_atom_;
Atom window_type_atom_;
Atom normal_window_type_atom_;
+ Atom icon_atom_;
bool has_composite_extension_ = false;
::Window selected_window_ = 0;
@@ -136,6 +169,7 @@ WindowCapturerLinux::WindowCapturerLinux(const DesktopCaptureOptions& options)
window_type_atom_ = XInternAtom(display(), "_NET_WM_WINDOW_TYPE", True);
normal_window_type_atom_ = XInternAtom(
display(), "_NET_WM_WINDOW_TYPE_NORMAL", True);
+ icon_atom_ = XInternAtom(display(), "_NET_WM_ICON", True);
int event_base, error_base, major_version, minor_version;
if (XCompositeQueryExtension(display(), &event_base, &error_base) &&
@@ -155,8 +189,7 @@ WindowCapturerLinux::~WindowCapturerLinux() {
}
bool WindowCapturerLinux::GetWindowList(WindowList* windows) {
- WindowList result;
-
+ windows->clear();
XErrorTrap error_trap(display());
int num_screens = XScreenCount(display());
@@ -180,8 +213,10 @@ bool WindowCapturerLinux::GetWindowList(WindowList* windows) {
if (app_window && !IsDesktopElement(app_window)) {
Window w;
w.id = app_window;
- if (GetWindowTitle(app_window, &w.title))
- result.push_back(w);
+ if (!GetWindowTitle(app_window, &w.title))
+ continue;
+ w.icon = GetWindowIcon(app_window);
+ windows->push_back(std::move(w));
}
}
@@ -189,8 +224,6 @@ bool WindowCapturerLinux::GetWindowList(WindowList* windows) {
XFree(children);
}
- windows->swap(result);
-
return true;
}
@@ -418,6 +451,46 @@ bool WindowCapturerLinux::GetWindowTitle(::Window window, std::string* title) {
return result;
}
+std::unique_ptr<DesktopFrame> WindowCapturerLinux::GetWindowIcon(
+ ::Window window) {
+ XWindowProperty<uint32_t> icon_property(display(), window, icon_atom_);
+
+ long* data = (long*)icon_property.data();
+
+ uint32_t length = icon_property.size();
+ if (length == 0)
+ return nullptr;
+
+ long width, height;
+ int start = 0;
+ uint32_t i = 0;
+ while (i < length) {
+ if (i == 0 || data[i] * data[i + 1] > width * height) {
+ width = data[i];
+ height = data[i + 1];
+ start = i + 2;
+ }
+ i = i + 2 + data[i] * data[i + 1];
+ }
+
+ std::unique_ptr<DesktopFrame> frame(
+ new BasicDesktopFrame(DesktopSize(width, height)));
+
+ uint32_t* frame_data = (uint32_t*)frame->data();
+ int dest_int_stride = frame->stride() / sizeof(uint32_t);
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x) {
+ frame_data[y * dest_int_stride + x] = PremultipliedColor(
+ static_cast<uint32_t>(data[start + y * width + x]));
+ }
+ }
+
+ frame->mutable_updated_region()->SetRect(
+ DesktopRect::MakeSize(frame->size()));
+
+ return frame;
+}
+
} // namespace
// static

Powered by Google App Engine
This is Rietveld 408576698