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

Side by Side Diff: webrtc/modules/desktop_capture/window_capturer_win.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 unified diff | Download patch
OLDNEW
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
11 #include "webrtc/modules/desktop_capture/window_capturer.h" 11 #include "webrtc/modules/desktop_capture/window_capturer.h"
12 12
13 #include <assert.h> 13 #include <assert.h>
14 14
15 #include <memory> 15 #include <memory>
16 16
17 #include "webrtc/base/checks.h" 17 #include "webrtc/base/checks.h"
18 #include "webrtc/base/constructormagic.h" 18 #include "webrtc/base/constructormagic.h"
19 #include "webrtc/base/win32.h" 19 #include "webrtc/base/win32.h"
20 #include "webrtc/modules/desktop_capture/desktop_frame_win.h" 20 #include "webrtc/modules/desktop_capture/desktop_frame_win.h"
21 #include "webrtc/modules/desktop_capture/win/window_capture_utils.h" 21 #include "webrtc/modules/desktop_capture/win/window_capture_utils.h"
22 #include "webrtc/system_wrappers/include/logging.h" 22 #include "webrtc/system_wrappers/include/logging.h"
23 23
24 namespace webrtc { 24 namespace webrtc {
25 25
26 namespace { 26 namespace {
27 27
28 void InitializeBitmapHeader(BITMAPV5HEADER* header, int width, int height) {
29 memset(header, 0, sizeof(BITMAPV5HEADER));
30 header->bV5Size = sizeof(BITMAPV5HEADER);
31
32 // Note that icons are created using top-down DIBs so we must negate the
33 // value used for the icon's height.
34 header->bV5Width = width;
35 header->bV5Height = -height;
36 header->bV5Planes = 1;
37 header->bV5Compression = BI_RGB;
38
39 // Initializing the bitmap format to 32 bit ARGB.
40 header->bV5BitCount = 32;
41 header->bV5RedMask = 0x00FF0000;
42 header->bV5GreenMask = 0x0000FF00;
43 header->bV5BlueMask = 0x000000FF;
44 header->bV5AlphaMask = 0xFF000000;
45
46 // Use the system color space. The default value is LCS_CALIBRATED_RGB, which
47 // causes us to crash if we don't specify the approprite gammas, etc. See
48 // <http://msdn.microsoft.com/en-us/library/ms536531(VS.85).aspx> and
49 // <http://b/1283121>.
50 header->bV5CSType = LCS_WINDOWS_COLOR_SPACE;
51
52 // Use a valid value for bV5Intent as 0 is not a valid one.
53 // <http://msdn.microsoft.com/en-us/library/dd183381(VS.85).aspx>
54 header->bV5Intent = LCS_GM_IMAGES;
55 }
56
57 std::unique_ptr<DesktopFrame> GetWindowIcon(HWND hwnd) {
58 HICON icon_handle =
59 reinterpret_cast<HICON>(SendMessage(hwnd, WM_GETICON, ICON_BIG, 0));
60 if (icon_handle == NULL)
61 icon_handle = (HICON)GetClassLongPtr(hwnd, GCLP_HICON);
62 if (icon_handle == NULL)
63 icon_handle =
64 reinterpret_cast<HICON>(SendMessage(hwnd, WM_GETICON, ICON_SMALL, 0));
65 if (icon_handle == NULL)
66 icon_handle =
67 reinterpret_cast<HICON>(SendMessage(hwnd, WM_GETICON, ICON_SMALL2, 0));
68 if (icon_handle == NULL)
69 icon_handle = (HICON)GetClassLongPtr(hwnd, GCLP_HICONSM);
70
71 if (icon_handle == NULL)
72 return nullptr;
73
74 ICONINFO icon_info;
75 ::GetIconInfo(icon_handle, &icon_info);
76
77 BITMAP bitmap_info = {0};
78 ::GetObject(icon_info.hbmMask, sizeof(bitmap_info), &bitmap_info);
79
80 std::unique_ptr<DesktopFrame> frame(new BasicDesktopFrame(
81 DesktopSize(bitmap_info.bmWidth, bitmap_info.bmHeight)));
82
83 BITMAPV5HEADER h;
84 InitializeBitmapHeader(&h, bitmap_info.bmWidth, bitmap_info.bmHeight);
85 HDC hdc = ::GetDC(NULL);
86 uint8_t* bits;
87 HBITMAP dib =
88 ::CreateDIBSection(hdc, reinterpret_cast<BITMAPINFO*>(&h), DIB_RGB_COLORS,
89 reinterpret_cast<void**>(&bits), NULL, 0);
90 HDC dib_dc = CreateCompatibleDC(hdc);
91 ::SelectObject(dib_dc, dib);
92 ::DrawIconEx(dib_dc, 0, 0, icon_handle, bitmap_info.bmWidth,
93 bitmap_info.bmHeight, 0, NULL, DI_NORMAL);
94 for (int y = 0; y < bitmap_info.bmHeight; ++y) {
95 memcpy(frame->data() + frame->stride() * y,
96 bits + bitmap_info.bmWidth * DesktopFrame::kBytesPerPixel * y,
97 DesktopFrame::kBytesPerPixel * bitmap_info.bmWidth);
98 }
99 return frame;
100 }
101
28 BOOL CALLBACK WindowsEnumerationHandler(HWND hwnd, LPARAM param) { 102 BOOL CALLBACK WindowsEnumerationHandler(HWND hwnd, LPARAM param) {
29 WindowCapturer::WindowList* list = 103 WindowCapturer::WindowList* list =
30 reinterpret_cast<WindowCapturer::WindowList*>(param); 104 reinterpret_cast<WindowCapturer::WindowList*>(param);
31 105
32 // Skip windows that are invisible, minimized, have no title, or are owned, 106 // Skip windows that are invisible, minimized, have no title, or are owned,
33 // unless they have the app window style set. 107 // unless they have the app window style set.
34 int len = GetWindowTextLength(hwnd); 108 int len = GetWindowTextLength(hwnd);
35 HWND owner = GetWindow(hwnd, GW_OWNER); 109 HWND owner = GetWindow(hwnd, GW_OWNER);
36 LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); 110 LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE);
37 if (len == 0 || IsIconic(hwnd) || !IsWindowVisible(hwnd) || 111 if (len == 0 || IsIconic(hwnd) || !IsWindowVisible(hwnd) ||
(...skipping 25 matching lines...) Expand all
63 } 137 }
64 138
65 WindowCapturer::Window window; 139 WindowCapturer::Window window;
66 window.id = reinterpret_cast<WindowCapturer::WindowId>(hwnd); 140 window.id = reinterpret_cast<WindowCapturer::WindowId>(hwnd);
67 141
68 const size_t kTitleLength = 500; 142 const size_t kTitleLength = 500;
69 WCHAR window_title[kTitleLength]; 143 WCHAR window_title[kTitleLength];
70 // Truncate the title if it's longer than kTitleLength. 144 // Truncate the title if it's longer than kTitleLength.
71 GetWindowText(hwnd, window_title, kTitleLength); 145 GetWindowText(hwnd, window_title, kTitleLength);
72 window.title = rtc::ToUtf8(window_title); 146 window.title = rtc::ToUtf8(window_title);
147 window.icon = GetWindowIcon(hwnd);
73 148
74 // Skip windows when we failed to convert the title or it is empty. 149 // Skip windows when we failed to convert the title or it is empty.
75 if (window.title.empty()) 150 if (window.title.empty())
76 return TRUE; 151 return TRUE;
77 152
78 list->push_back(window); 153 list->push_back(std::move(window));
79 154
80 return TRUE; 155 return TRUE;
81 } 156 }
82 157
83 class WindowCapturerWin : public WindowCapturer { 158 class WindowCapturerWin : public WindowCapturer {
84 public: 159 public:
85 WindowCapturerWin(); 160 WindowCapturerWin();
86 virtual ~WindowCapturerWin(); 161 virtual ~WindowCapturerWin();
87 162
88 // WindowCapturer interface. 163 // WindowCapturer interface.
(...skipping 20 matching lines...) Expand all
109 // are interleaved with Capture() calls. 184 // are interleaved with Capture() calls.
110 std::map<HWND, DesktopSize> window_size_map_; 185 std::map<HWND, DesktopSize> window_size_map_;
111 186
112 RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerWin); 187 RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerWin);
113 }; 188 };
114 189
115 WindowCapturerWin::WindowCapturerWin() {} 190 WindowCapturerWin::WindowCapturerWin() {}
116 WindowCapturerWin::~WindowCapturerWin() {} 191 WindowCapturerWin::~WindowCapturerWin() {}
117 192
118 bool WindowCapturerWin::GetWindowList(WindowList* windows) { 193 bool WindowCapturerWin::GetWindowList(WindowList* windows) {
119 WindowList result; 194 windows->clear();
120 LPARAM param = reinterpret_cast<LPARAM>(&result); 195 LPARAM param = reinterpret_cast<LPARAM>(windows);
121 if (!EnumWindows(&WindowsEnumerationHandler, param)) 196 if (!EnumWindows(&WindowsEnumerationHandler, param))
122 return false; 197 return false;
123 windows->swap(result);
124 198
125 std::map<HWND, DesktopSize> new_map; 199 std::map<HWND, DesktopSize> new_map;
126 for (const auto& item : *windows) { 200 for (const auto& item : *windows) {
127 HWND hwnd = reinterpret_cast<HWND>(item.id); 201 HWND hwnd = reinterpret_cast<HWND>(item.id);
128 new_map[hwnd] = window_size_map_[hwnd]; 202 new_map[hwnd] = window_size_map_[hwnd];
129 } 203 }
130 window_size_map_.swap(new_map); 204 window_size_map_.swap(new_map);
131 205
132 return true; 206 return true;
133 } 207 }
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 } 337 }
264 338
265 } // namespace 339 } // namespace
266 340
267 // static 341 // static
268 WindowCapturer* WindowCapturer::Create(const DesktopCaptureOptions& options) { 342 WindowCapturer* WindowCapturer::Create(const DesktopCaptureOptions& options) {
269 return new WindowCapturerWin(); 343 return new WindowCapturerWin();
270 } 344 }
271 345
272 } // namespace webrtc 346 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698