Chromium Code Reviews| Index: webrtc/modules/desktop_capture/mac/window_list_utils.mm |
| diff --git a/webrtc/modules/desktop_capture/mac/window_list_utils.cc b/webrtc/modules/desktop_capture/mac/window_list_utils.mm |
| similarity index 53% |
| rename from webrtc/modules/desktop_capture/mac/window_list_utils.cc |
| rename to webrtc/modules/desktop_capture/mac/window_list_utils.mm |
| index 0261c45a69d35f6f011f6ad4286ffae11b183a4b..ad73484decca5357dba4f98688828c09b0c39451 100644 |
| --- a/webrtc/modules/desktop_capture/mac/window_list_utils.cc |
| +++ b/webrtc/modules/desktop_capture/mac/window_list_utils.mm |
| @@ -11,11 +11,72 @@ |
| #include "webrtc/modules/desktop_capture/mac/window_list_utils.h" |
| #include <ApplicationServices/ApplicationServices.h> |
| +#include <Cocoa/Cocoa.h> |
| #include "webrtc/base/macutils.h" |
| +#include "webrtc/system_wrappers/include/logging.h" |
| namespace webrtc { |
| +std::unique_ptr<DesktopFrame> GetWindowIcon(WindowId id) { |
| + CGWindowID ids[1]; |
| + ids[0] = id; |
| + CFArrayRef window_id_array = |
| + CFArrayCreate(nullptr, reinterpret_cast<const void**>(&ids), 1, nullptr); |
| + CFArrayRef window_array = |
| + CGWindowListCreateDescriptionFromArray(window_id_array); |
| + if (!window_array || 0 == CFArrayGetCount(window_array)) { |
| + return nullptr; |
| + } |
| + |
| + CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>( |
| + CFArrayGetValueAtIndex(window_array, 0)); |
| + CFNumberRef pid_ref = reinterpret_cast<CFNumberRef>( |
| + CFDictionaryGetValue(window, kCGWindowOwnerPID)); |
| + |
| + int pid; |
| + CFNumberGetValue(pid_ref, kCFNumberIntType, &pid); |
| + |
| + NSImage* icon_image = |
| + [[NSRunningApplication runningApplicationWithProcessIdentifier:pid] icon]; |
| + |
| + int width = [icon_image size].width; |
| + int height = [icon_image size].height; |
| + |
| + CGImageRef cg_icon_image = |
| + [icon_image CGImageForProposedRect:nil context:nil hints:nil]; |
| + |
| + int bits_per_pixel = CGImageGetBitsPerPixel(cg_icon_image); |
| + if (bits_per_pixel != 32) { |
| + LOG(LS_ERROR) << "Unsupported icon image depth: " << bits_per_pixel; |
| + return nullptr; |
| + } |
| + |
| + CGDataProviderRef provider = CGImageGetDataProvider(cg_icon_image); |
| + CFDataRef cf_data = CGDataProviderCopyData(provider); |
| + std::unique_ptr<DesktopFrame> frame( |
| + new BasicDesktopFrame(DesktopSize(width, height))); |
| + |
| + int src_stride = CGImageGetBytesPerRow(cg_icon_image); |
| + const uint32_t* src_data = (const uint32_t*)CFDataGetBytePtr(cf_data); |
| + uint32_t* des_data = (uint32_t*)frame->data(); |
| + |
| + for (int y = 0; y < height; ++y) { |
|
Sergey Ulanov
2016/08/12 06:00:29
Use ABGRToARGB() from libyuv to convert ABGR to AR
|
| + for (int x = 0; x < width; ++x) { |
| + uint32_t color = src_data[src_stride / 4 * y + x]; |
| + uint32_t alpha = color & 0xFF000000; |
| + uint32_t blue = color & 0x00FF0000; |
| + uint32_t green = color & 0x0000FF00; |
| + uint32_t red = color & 0x000000FF; |
| + uint32_t colorD = alpha | (blue >> 16) | green | (red << 16); |
| + des_data[frame->stride() / 4 * y + x] = colorD; |
| + } |
| + } |
| + CFRelease(cf_data); |
| + |
| + return frame; |
| +} |
| + |
| bool GetWindowList(WindowCapturer::WindowList* windows) { |
| // Only get on screen, non-desktop windows. |
| CFArrayRef window_array = CGWindowListCopyWindowInfo( |
| @@ -47,11 +108,11 @@ bool GetWindowList(WindowCapturer::WindowList* windows) { |
| CFNumberGetValue(window_id, kCFNumberIntType, &id); |
| WindowCapturer::Window window; |
| window.id = id; |
| - if (!rtc::ToUtf8(window_title, &(window.title)) || |
| - window.title.empty()) { |
| + if (!rtc::ToUtf8(window_title, &(window.title)) || window.title.empty()) { |
| continue; |
| } |
| - windows->push_back(window); |
| + window.icon = GetWindowIcon(id); |
| + windows->push_back(std::move(window)); |
| } |
| } |
| @@ -60,9 +121,8 @@ bool GetWindowList(WindowCapturer::WindowList* windows) { |
| } |
| // Returns true if the window is occupying a full screen. |
| -bool IsWindowFullScreen( |
| - const MacDesktopConfiguration& desktop_config, |
| - CFDictionaryRef window) { |
| +bool IsWindowFullScreen(const MacDesktopConfiguration& desktop_config, |
| + CFDictionaryRef window) { |
| bool fullscreen = false; |
| CFDictionaryRef bounds_ref = reinterpret_cast<CFDictionaryRef>( |
| CFDictionaryGetValue(window, kCGWindowBounds)); |
| @@ -73,10 +133,9 @@ bool IsWindowFullScreen( |
| for (MacDisplayConfigurations::const_iterator it = |
| desktop_config.displays.begin(); |
| it != desktop_config.displays.end(); ++it) { |
| - if (it->bounds.equals(DesktopRect::MakeXYWH(bounds.origin.x, |
| - bounds.origin.y, |
| - bounds.size.width, |
| - bounds.size.height))) { |
| + if (it->bounds.equals( |
| + DesktopRect::MakeXYWH(bounds.origin.x, bounds.origin.y, |
| + bounds.size.width, bounds.size.height))) { |
| fullscreen = true; |
| break; |
| } |
| @@ -89,7 +148,7 @@ bool IsWindowFullScreen( |
| // Returns true if the window is minimized. |
| bool IsWindowMinimized(CGWindowID id) { |
| CFArrayRef window_id_array = |
| - CFArrayCreate(NULL, reinterpret_cast<const void **>(&id), 1, NULL); |
| + CFArrayCreate(NULL, reinterpret_cast<const void**>(&id), 1, NULL); |
| CFArrayRef window_array = |
| CGWindowListCreateDescriptionFromArray(window_id_array); |
| bool minimized = false; |
| @@ -97,7 +156,7 @@ bool IsWindowMinimized(CGWindowID id) { |
| if (window_array && CFArrayGetCount(window_array)) { |
| CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>( |
| CFArrayGetValueAtIndex(window_array, 0)); |
| - CFBooleanRef on_screen = reinterpret_cast<CFBooleanRef>( |
| + CFBooleanRef on_screen = reinterpret_cast<CFBooleanRef>( |
| CFDictionaryGetValue(window, kCGWindowIsOnscreen)); |
| minimized = !on_screen; |
| @@ -109,6 +168,4 @@ bool IsWindowMinimized(CGWindowID id) { |
| return minimized; |
| } |
| - |
| - |
| } // namespace webrtc |