OLD | NEW |
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/win/cursor.h" | 11 #include "webrtc/modules/desktop_capture/win/cursor.h" |
12 | 12 |
13 #include <algorithm> | 13 #include <algorithm> |
14 #include <memory> | 14 #include <memory> |
15 | 15 |
16 #include "webrtc/modules/desktop_capture/win/scoped_gdi_object.h" | 16 #include "webrtc/modules/desktop_capture/win/scoped_gdi_object.h" |
17 #include "webrtc/modules/desktop_capture/desktop_frame.h" | 17 #include "webrtc/modules/desktop_capture/desktop_frame.h" |
18 #include "webrtc/modules/desktop_capture/desktop_geometry.h" | 18 #include "webrtc/modules/desktop_capture/desktop_geometry.h" |
19 #include "webrtc/modules/desktop_capture/mouse_cursor.h" | 19 #include "webrtc/modules/desktop_capture/mouse_cursor.h" |
20 #include "webrtc/system_wrappers/include/logging.h" | |
21 #include "webrtc/typedefs.h" | 20 #include "webrtc/typedefs.h" |
22 | 21 |
23 namespace webrtc { | 22 namespace webrtc { |
24 | 23 |
25 namespace { | 24 namespace { |
26 | 25 |
27 #if defined(WEBRTC_ARCH_LITTLE_ENDIAN) | 26 #if defined(WEBRTC_ARCH_LITTLE_ENDIAN) |
28 | 27 |
29 #define RGBA(r, g, b, a) \ | 28 #define RGBA(r, g, b, a) \ |
30 ((((a) << 24) & 0xff000000) | \ | 29 ((((a) << 24) & 0xff000000) | \ |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 } | 104 } |
106 | 105 |
107 return false; | 106 return false; |
108 } | 107 } |
109 | 108 |
110 } // namespace | 109 } // namespace |
111 | 110 |
112 MouseCursor* CreateMouseCursorFromHCursor(HDC dc, HCURSOR cursor) { | 111 MouseCursor* CreateMouseCursorFromHCursor(HDC dc, HCURSOR cursor) { |
113 ICONINFO iinfo; | 112 ICONINFO iinfo; |
114 if (!GetIconInfo(cursor, &iinfo)) { | 113 if (!GetIconInfo(cursor, &iinfo)) { |
115 LOG_F(LS_ERROR) << "Unable to get cursor icon info. Error = " | |
116 << GetLastError(); | |
117 return NULL; | 114 return NULL; |
118 } | 115 } |
119 | 116 |
120 int hotspot_x = iinfo.xHotspot; | 117 int hotspot_x = iinfo.xHotspot; |
121 int hotspot_y = iinfo.yHotspot; | 118 int hotspot_y = iinfo.yHotspot; |
122 | 119 |
123 // Make sure the bitmaps will be freed. | 120 // Make sure the bitmaps will be freed. |
124 win::ScopedBitmap scoped_mask(iinfo.hbmMask); | 121 win::ScopedBitmap scoped_mask(iinfo.hbmMask); |
125 win::ScopedBitmap scoped_color(iinfo.hbmColor); | 122 win::ScopedBitmap scoped_color(iinfo.hbmColor); |
126 bool is_color = iinfo.hbmColor != NULL; | 123 bool is_color = iinfo.hbmColor != NULL; |
127 | 124 |
128 // Get |scoped_mask| dimensions. | 125 // Get |scoped_mask| dimensions. |
129 BITMAP bitmap_info; | 126 BITMAP bitmap_info; |
130 if (!GetObject(scoped_mask, sizeof(bitmap_info), &bitmap_info)) { | 127 if (!GetObject(scoped_mask, sizeof(bitmap_info), &bitmap_info)) { |
131 LOG_F(LS_ERROR) << "Unable to get bitmap info. Error = " | |
132 << GetLastError(); | |
133 return NULL; | 128 return NULL; |
134 } | 129 } |
135 | 130 |
136 int width = bitmap_info.bmWidth; | 131 int width = bitmap_info.bmWidth; |
137 int height = bitmap_info.bmHeight; | 132 int height = bitmap_info.bmHeight; |
138 std::unique_ptr<uint32_t[]> mask_data(new uint32_t[width * height]); | 133 std::unique_ptr<uint32_t[]> mask_data(new uint32_t[width * height]); |
139 | 134 |
140 // Get pixel data from |scoped_mask| converting it to 32bpp along the way. | 135 // Get pixel data from |scoped_mask| converting it to 32bpp along the way. |
141 // GetDIBits() sets the alpha component of every pixel to 0. | 136 // GetDIBits() sets the alpha component of every pixel to 0. |
142 BITMAPV5HEADER bmi = {0}; | 137 BITMAPV5HEADER bmi = {0}; |
143 bmi.bV5Size = sizeof(bmi); | 138 bmi.bV5Size = sizeof(bmi); |
144 bmi.bV5Width = width; | 139 bmi.bV5Width = width; |
145 bmi.bV5Height = -height; // request a top-down bitmap. | 140 bmi.bV5Height = -height; // request a top-down bitmap. |
146 bmi.bV5Planes = 1; | 141 bmi.bV5Planes = 1; |
147 bmi.bV5BitCount = kBytesPerPixel * 8; | 142 bmi.bV5BitCount = kBytesPerPixel * 8; |
148 bmi.bV5Compression = BI_RGB; | 143 bmi.bV5Compression = BI_RGB; |
149 bmi.bV5AlphaMask = 0xff000000; | 144 bmi.bV5AlphaMask = 0xff000000; |
150 bmi.bV5CSType = LCS_WINDOWS_COLOR_SPACE; | 145 bmi.bV5CSType = LCS_WINDOWS_COLOR_SPACE; |
151 bmi.bV5Intent = LCS_GM_BUSINESS; | 146 bmi.bV5Intent = LCS_GM_BUSINESS; |
152 if (!GetDIBits(dc, | 147 if (!GetDIBits(dc, |
153 scoped_mask, | 148 scoped_mask, |
154 0, | 149 0, |
155 height, | 150 height, |
156 mask_data.get(), | 151 mask_data.get(), |
157 reinterpret_cast<BITMAPINFO*>(&bmi), | 152 reinterpret_cast<BITMAPINFO*>(&bmi), |
158 DIB_RGB_COLORS)) { | 153 DIB_RGB_COLORS)) { |
159 LOG_F(LS_ERROR) << "Unable to get bitmap bits. Error = " | |
160 << GetLastError(); | |
161 return NULL; | 154 return NULL; |
162 } | 155 } |
163 | 156 |
164 uint32_t* mask_plane = mask_data.get(); | 157 uint32_t* mask_plane = mask_data.get(); |
165 std::unique_ptr<DesktopFrame> image( | 158 std::unique_ptr<DesktopFrame> image( |
166 new BasicDesktopFrame(DesktopSize(width, height))); | 159 new BasicDesktopFrame(DesktopSize(width, height))); |
167 bool has_alpha = false; | 160 bool has_alpha = false; |
168 | 161 |
169 if (is_color) { | 162 if (is_color) { |
170 image.reset(new BasicDesktopFrame(DesktopSize(width, height))); | 163 image.reset(new BasicDesktopFrame(DesktopSize(width, height))); |
171 // Get the pixels from the color bitmap. | 164 // Get the pixels from the color bitmap. |
172 if (!GetDIBits(dc, | 165 if (!GetDIBits(dc, |
173 scoped_color, | 166 scoped_color, |
174 0, | 167 0, |
175 height, | 168 height, |
176 image->data(), | 169 image->data(), |
177 reinterpret_cast<BITMAPINFO*>(&bmi), | 170 reinterpret_cast<BITMAPINFO*>(&bmi), |
178 DIB_RGB_COLORS)) { | 171 DIB_RGB_COLORS)) { |
179 LOG_F(LS_ERROR) << "Unable to get bitmap bits. Error = " | |
180 << GetLastError(); | |
181 return NULL; | 172 return NULL; |
182 } | 173 } |
183 | 174 |
184 // GetDIBits() does not provide any indication whether the bitmap has alpha | 175 // GetDIBits() does not provide any indication whether the bitmap has alpha |
185 // channel, so we use HasAlphaChannel() below to find it out. | 176 // channel, so we use HasAlphaChannel() below to find it out. |
186 has_alpha = HasAlphaChannel(reinterpret_cast<uint32_t*>(image->data()), | 177 has_alpha = HasAlphaChannel(reinterpret_cast<uint32_t*>(image->data()), |
187 width, width, height); | 178 width, width, height); |
188 } else { | 179 } else { |
189 // For non-color cursors, the mask contains both an AND and an XOR mask and | 180 // For non-color cursors, the mask contains both an AND and an XOR mask and |
190 // the height includes both. Thus, the width is correct, but we need to | 181 // the height includes both. Thus, the width is correct, but we need to |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 | 230 |
240 // Pre-multiply the resulting pixels since MouseCursor uses premultiplied | 231 // Pre-multiply the resulting pixels since MouseCursor uses premultiplied |
241 // images. | 232 // images. |
242 AlphaMul(reinterpret_cast<uint32_t*>(image->data()), width, height); | 233 AlphaMul(reinterpret_cast<uint32_t*>(image->data()), width, height); |
243 | 234 |
244 return new MouseCursor( | 235 return new MouseCursor( |
245 image.release(), DesktopVector(hotspot_x, hotspot_y)); | 236 image.release(), DesktopVector(hotspot_x, hotspot_y)); |
246 } | 237 } |
247 | 238 |
248 } // namespace webrtc | 239 } // namespace webrtc |
OLD | NEW |