1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/media/webrtc/window_icon_util.h"
6 
7 #include "ui/base/x/x11_util.h"
8 #include "ui/gfx/x/x11_atom_cache.h"
9 
GetWindowIcon(content::DesktopMediaID id)10 gfx::ImageSkia GetWindowIcon(content::DesktopMediaID id) {
11   DCHECK(id.type == content::DesktopMediaID::TYPE_WINDOW);
12 
13   std::vector<uint32_t> data;
14   if (!ui::GetArrayProperty(static_cast<x11::Window>(id.id),
15                             gfx::GetAtom("_NET_WM_ICON"), &data)) {
16     return gfx::ImageSkia();
17   }
18 
19   // The format of |data| is concatenation of sections like
20   // [width, height, pixel data of size width * height], and the total bytes
21   // number of |data| is |size|. And here we are picking the largest icon.
22   int width = 0;
23   int height = 0;
24   int start = 0;
25   size_t i = 0;
26   while (i + 1 < data.size()) {
27     if ((i == 0 || static_cast<int>(data[i] * data[i + 1]) > width * height) &&
28         (i + 1 + data[i] * data[i + 1] < data.size())) {
29       width = static_cast<int>(data[i]);
30       height = static_cast<int>(data[i + 1]);
31       start = i + 2;
32     }
33     i = i + 2 + static_cast<int>(data[i] * data[i + 1]);
34   }
35 
36   SkBitmap result;
37   SkImageInfo info = SkImageInfo::MakeN32(width, height, kUnpremul_SkAlphaType);
38   result.allocPixels(info);
39 
40   uint32_t* pixels_data = reinterpret_cast<uint32_t*>(result.getPixels());
41 
42   for (long y = 0; y < height; ++y) {
43     for (long x = 0; x < width; ++x) {
44       pixels_data[result.rowBytesAsPixels() * y + x] =
45           static_cast<uint32_t>(data[start + width * y + x]);
46     }
47   }
48 
49   return gfx::ImageSkia::CreateFrom1xBitmap(result);
50 }
51