зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset a5723795cd1f (bug 1036653)
This commit is contained in:
Родитель
04e66f1b43
Коммит
5cb2a8c76e
|
@ -7,16 +7,11 @@
|
|||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/modules/desktop_capture/window_capturer.h"
|
||||
#include "webrtc/modules/desktop_capture/app_capturer.h"
|
||||
#include "webrtc/modules/desktop_capture/screen_capturer.h"
|
||||
#include "webrtc/modules/desktop_capture/shared_desktop_frame.h"
|
||||
#include "webrtc/modules/desktop_capture/win/win_shared.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <windows.h>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
#include "webrtc/modules/desktop_capture/desktop_frame_win.h"
|
||||
#include "webrtc/system_wrappers/interface/logging.h"
|
||||
|
@ -26,130 +21,59 @@ namespace webrtc {
|
|||
|
||||
namespace {
|
||||
|
||||
// Proxy over the WebRTC window capturer, to allow post-processing
|
||||
// of the frame to merge multiple window capture frames into a single frame
|
||||
class WindowsCapturerProxy : DesktopCapturer::Callback {
|
||||
public:
|
||||
WindowsCapturerProxy() :
|
||||
window_capturer_(WindowCapturer::Create()) {
|
||||
window_capturer_->Start(this);
|
||||
}
|
||||
~WindowsCapturerProxy(){}
|
||||
std::string Utf16ToUtf8(const WCHAR* str) {
|
||||
int len_utf8 = WideCharToMultiByte(CP_UTF8, 0, str, -1,
|
||||
NULL, 0, NULL, NULL);
|
||||
if (len_utf8 <= 0)
|
||||
return std::string();
|
||||
std::string result(len_utf8, '\0');
|
||||
int rv = WideCharToMultiByte(CP_UTF8, 0, str, -1,
|
||||
&*(result.begin()), len_utf8, NULL, NULL);
|
||||
if (rv != len_utf8)
|
||||
assert(false);
|
||||
|
||||
void SelectWindow(HWND hwnd) { window_capturer_->SelectWindow(reinterpret_cast<WindowId>(hwnd)); }
|
||||
scoped_ptr<DesktopFrame>& GetFrame() { return frame_; }
|
||||
void Capture(const DesktopRegion& region) { window_capturer_->Capture(region); }
|
||||
return result;
|
||||
}
|
||||
|
||||
// Callback interface
|
||||
virtual SharedMemory *CreateSharedMemory(size_t) OVERRIDE { return NULL; }
|
||||
virtual void OnCaptureCompleted(DesktopFrame *frame) OVERRIDE { frame_.reset(frame); }
|
||||
private:
|
||||
scoped_ptr<WindowCapturer> window_capturer_;
|
||||
scoped_ptr<DesktopFrame> frame_;
|
||||
};
|
||||
|
||||
// Proxy over the WebRTC screen capturer, to allow post-processing
|
||||
// of the frame to mask out non-application windows
|
||||
class ScreenCapturerProxy : DesktopCapturer::Callback {
|
||||
public:
|
||||
ScreenCapturerProxy(const DesktopCaptureOptions& options) :
|
||||
screen_capturer_(ScreenCapturer::Create(options)) {
|
||||
screen_capturer_->SelectScreen(kFullDesktopScreenId);
|
||||
screen_capturer_->Start(this);
|
||||
}
|
||||
void Capture(const DesktopRegion& region) { screen_capturer_->Capture(region); }
|
||||
scoped_ptr<DesktopFrame>& GetFrame() { return frame_; }
|
||||
|
||||
// Callback interface
|
||||
virtual SharedMemory *CreateSharedMemory(size_t) OVERRIDE { return NULL; }
|
||||
virtual void OnCaptureCompleted(DesktopFrame *frame) OVERRIDE { frame_.reset(frame); }
|
||||
protected:
|
||||
scoped_ptr<ScreenCapturer> screen_capturer_;
|
||||
scoped_ptr<DesktopFrame> frame_;
|
||||
};
|
||||
|
||||
class AppCapturerWin : public AppCapturer {
|
||||
public:
|
||||
AppCapturerWin(const DesktopCaptureOptions& options);
|
||||
AppCapturerWin();
|
||||
virtual ~AppCapturerWin();
|
||||
|
||||
// AppCapturer interface.
|
||||
virtual bool GetAppList(AppList* apps) OVERRIDE;
|
||||
virtual bool SelectApp(ProcessId processId) OVERRIDE;
|
||||
virtual bool SelectApp(ProcessId id) OVERRIDE;
|
||||
virtual bool BringAppToFront() OVERRIDE;
|
||||
|
||||
// DesktopCapturer interface.
|
||||
virtual void Start(Callback* callback) OVERRIDE;
|
||||
virtual void Capture(const DesktopRegion& region) OVERRIDE;
|
||||
|
||||
struct WindowItem {
|
||||
HWND handle;
|
||||
RECT bounds;
|
||||
bool owned;
|
||||
};
|
||||
|
||||
struct EnumWindowsCtx {
|
||||
ProcessId process_id;
|
||||
std::vector<WindowItem> windows;
|
||||
bool list_all;
|
||||
};
|
||||
|
||||
static BOOL CALLBACK EnumWindowsProc(HWND handle, LPARAM lParam);
|
||||
protected:
|
||||
void CaptureByWebRTC(const DesktopRegion& region);
|
||||
void CaptureBySample(const DesktopRegion& region);
|
||||
private:
|
||||
Callback* callback_;
|
||||
|
||||
ProcessId processId_;
|
||||
|
||||
// Sample Mode
|
||||
ScreenCapturerProxy screen_capturer_proxy_;
|
||||
// Mask of foreground (non-app windows in front of selected)
|
||||
HRGN hrgn_foreground_;
|
||||
// Mask of background (desktop, non-app windows behind selected)
|
||||
HRGN hrgn_background_;
|
||||
// Region of selected windows
|
||||
HRGN hrgn_visual_;
|
||||
|
||||
void UpdateRegions();
|
||||
|
||||
// WebRTC Window mode
|
||||
WindowsCapturerProxy window_capturer_proxy_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AppCapturerWin);
|
||||
};
|
||||
|
||||
AppCapturerWin::AppCapturerWin(const DesktopCaptureOptions& options)
|
||||
AppCapturerWin::AppCapturerWin()
|
||||
: callback_(NULL),
|
||||
screen_capturer_proxy_(options),
|
||||
processId_(NULL) {
|
||||
// Initialize regions to zero
|
||||
hrgn_foreground_ = CreateRectRgn(0, 0, 0, 0);
|
||||
hrgn_background_ = CreateRectRgn(0, 0, 0, 0);
|
||||
hrgn_visual_ = CreateRectRgn(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
AppCapturerWin::~AppCapturerWin() {
|
||||
if (hrgn_foreground_) {
|
||||
DeleteObject(hrgn_foreground_);
|
||||
}
|
||||
if (hrgn_background_) {
|
||||
DeleteObject(hrgn_background_);
|
||||
}
|
||||
if (hrgn_visual_) {
|
||||
DeleteObject(hrgn_visual_);
|
||||
}
|
||||
}
|
||||
|
||||
// AppCapturer interface.
|
||||
bool AppCapturerWin::GetAppList(AppList* apps){
|
||||
// Implemented via DesktopDeviceInfo
|
||||
// Not implemented yet: See Bug 1036653
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AppCapturerWin::SelectApp(ProcessId processId) {
|
||||
processId_ = processId;
|
||||
bool AppCapturerWin::SelectApp(ProcessId id) {
|
||||
// Not implemented yet: See Bug 1036653
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -166,251 +90,14 @@ void AppCapturerWin::Start(Callback* callback) {
|
|||
callback_ = callback;
|
||||
}
|
||||
void AppCapturerWin::Capture(const DesktopRegion& region) {
|
||||
CaptureBySample(region);
|
||||
}
|
||||
|
||||
BOOL CALLBACK AppCapturerWin::EnumWindowsProc(HWND handle, LPARAM lParam) {
|
||||
EnumWindowsCtx *pEnumWindowsCtx = reinterpret_cast<EnumWindowsCtx *>(lParam);
|
||||
if (!pEnumWindowsCtx) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DWORD procId = -1;
|
||||
GetWindowThreadProcessId(handle, &procId);
|
||||
if (procId == pEnumWindowsCtx->process_id || pEnumWindowsCtx->list_all) {
|
||||
WindowItem window_item;
|
||||
window_item.handle = handle;
|
||||
|
||||
if (!IsWindowVisible(handle) || IsIconic(handle)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GetWindowRect(handle, &window_item.bounds);
|
||||
window_item.owned = (procId == pEnumWindowsCtx->process_id);
|
||||
pEnumWindowsCtx->windows.push_back(window_item);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void AppCapturerWin::CaptureByWebRTC(const DesktopRegion& region) {
|
||||
// List Windows of selected application
|
||||
EnumWindowsCtx lParamEnumWindows;
|
||||
lParamEnumWindows.process_id = processId_;
|
||||
lParamEnumWindows.list_all = false;
|
||||
EnumWindows(EnumWindowsProc, (LPARAM)&lParamEnumWindows);
|
||||
|
||||
// Prepare capture dc context
|
||||
// TODO: handle multi-monitor setups; see Bug 1037997
|
||||
DesktopRect rcDesktop(DesktopRect::MakeXYWH(
|
||||
GetSystemMetrics(SM_XVIRTUALSCREEN),
|
||||
GetSystemMetrics(SM_YVIRTUALSCREEN),
|
||||
GetSystemMetrics(SM_CXVIRTUALSCREEN),
|
||||
GetSystemMetrics(SM_CYVIRTUALSCREEN)
|
||||
));
|
||||
|
||||
HDC dcScreen = GetDC(NULL);
|
||||
HDC memDcCapture = CreateCompatibleDC(dcScreen);
|
||||
if (dcScreen) {
|
||||
ReleaseDC(NULL, dcScreen);
|
||||
}
|
||||
|
||||
scoped_ptr<DesktopFrameWin> frameCapture(DesktopFrameWin::Create(
|
||||
DesktopSize(rcDesktop.width(), rcDesktop.height()),
|
||||
NULL, memDcCapture));
|
||||
HBITMAP bmpOrigin = static_cast<HBITMAP>(SelectObject(memDcCapture, frameCapture->bitmap()));
|
||||
BOOL bCaptureAppResult = false;
|
||||
// Capture and Combine all windows into memDcCapture
|
||||
std::vector<WindowItem>::reverse_iterator itItem;
|
||||
for (itItem = lParamEnumWindows.windows.rbegin(); itItem != lParamEnumWindows.windows.rend(); itItem++) {
|
||||
WindowItem window_item = *itItem;
|
||||
HWND hWndCapturer = window_item.handle;
|
||||
if (!IsWindow(hWndCapturer) || !IsWindowVisible(hWndCapturer) || IsIconic(hWndCapturer)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
HDC memDcWin = NULL;
|
||||
HBITMAP bmpOriginWin = NULL;
|
||||
HBITMAP hBitmapFrame = NULL;
|
||||
HDC dcWin = NULL;
|
||||
RECT rcWin = window_item.bounds;
|
||||
bool bCaptureResult = false;
|
||||
scoped_ptr<DesktopFrameWin> frame;
|
||||
do {
|
||||
if (rcWin.left == rcWin.right || rcWin.top == rcWin.bottom) {
|
||||
break;
|
||||
}
|
||||
|
||||
dcWin = GetWindowDC(hWndCapturer);
|
||||
if (!dcWin) {
|
||||
break;
|
||||
}
|
||||
memDcWin = CreateCompatibleDC(dcWin);
|
||||
|
||||
// Capture
|
||||
window_capturer_proxy_.SelectWindow(hWndCapturer);
|
||||
window_capturer_proxy_.Capture(region);
|
||||
if (window_capturer_proxy_.GetFrame() != NULL) {
|
||||
DesktopFrameWin *pDesktopFrameWin = reinterpret_cast<DesktopFrameWin *>(
|
||||
window_capturer_proxy_.GetFrame().get());
|
||||
if (pDesktopFrameWin) {
|
||||
hBitmapFrame = pDesktopFrameWin->bitmap();
|
||||
}
|
||||
if (GetObjectType(hBitmapFrame) != OBJ_BITMAP) {
|
||||
hBitmapFrame = NULL;
|
||||
}
|
||||
}
|
||||
if (!hBitmapFrame) {
|
||||
break;
|
||||
}
|
||||
bmpOriginWin = static_cast<HBITMAP>(SelectObject(memDcWin, hBitmapFrame));
|
||||
} while(0);
|
||||
|
||||
// bitblt to capture memDcCapture
|
||||
if (bmpOriginWin) {
|
||||
BitBlt(memDcCapture,
|
||||
rcWin.left, rcWin.top, rcWin.right - rcWin.left, rcWin.bottom - rcWin.top,
|
||||
memDcWin, 0, 0, SRCCOPY);
|
||||
bCaptureAppResult = true;
|
||||
}
|
||||
|
||||
// Clean resource
|
||||
if (memDcWin) {
|
||||
SelectObject(memDcWin, bmpOriginWin);
|
||||
DeleteDC(memDcWin);
|
||||
}
|
||||
if (dcWin) {
|
||||
ReleaseDC(hWndCapturer, dcWin);
|
||||
}
|
||||
}
|
||||
|
||||
// Clean resource
|
||||
if (memDcCapture) {
|
||||
SelectObject(memDcCapture, bmpOrigin);
|
||||
DeleteDC(memDcCapture);
|
||||
}
|
||||
|
||||
// trigger event
|
||||
if (bCaptureAppResult) {
|
||||
callback_->OnCaptureCompleted(frameCapture.release());
|
||||
}
|
||||
}
|
||||
|
||||
// Application Capturer by sample and region
|
||||
void AppCapturerWin::CaptureBySample(const DesktopRegion& region){
|
||||
// capture entire screen
|
||||
screen_capturer_proxy_.Capture(region);
|
||||
|
||||
HBITMAP hBitmapFrame = NULL;
|
||||
if (screen_capturer_proxy_.GetFrame() != NULL) {
|
||||
SharedDesktopFrame* pSharedDesktopFrame = reinterpret_cast<SharedDesktopFrame*>(
|
||||
screen_capturer_proxy_.GetFrame().get());
|
||||
if (pSharedDesktopFrame) {
|
||||
DesktopFrameWin *pDesktopFrameWin =reinterpret_cast<DesktopFrameWin *>(
|
||||
pSharedDesktopFrame->GetUnderlyingFrame());
|
||||
if (pDesktopFrameWin) {
|
||||
hBitmapFrame = pDesktopFrameWin->bitmap();
|
||||
}
|
||||
if (GetObjectType(hBitmapFrame) != OBJ_BITMAP) {
|
||||
hBitmapFrame = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hBitmapFrame) {
|
||||
// calculate app visual/foreground region
|
||||
UpdateRegions();
|
||||
|
||||
HDC dcScreen = GetDC(NULL);
|
||||
HDC memDcCapture = CreateCompatibleDC(dcScreen);
|
||||
|
||||
RECT rcScreen = {0, 0,
|
||||
screen_capturer_proxy_.GetFrame()->size().width(),
|
||||
screen_capturer_proxy_.GetFrame()->size().height()
|
||||
};
|
||||
|
||||
HBITMAP bmpOriginCapture = (HBITMAP)SelectObject(memDcCapture, hBitmapFrame);
|
||||
|
||||
// TODO: background/foreground mask colors should be configurable; see Bug 1054503
|
||||
// fill background
|
||||
SelectClipRgn(memDcCapture, hrgn_background_);
|
||||
SelectObject(memDcCapture, GetStockObject(DC_BRUSH));
|
||||
SetDCBrushColor(memDcCapture, RGB(0, 0, 0));
|
||||
FillRect(memDcCapture, &rcScreen, (HBRUSH)GetStockObject(DC_BRUSH));
|
||||
|
||||
// fill foreground
|
||||
SelectClipRgn(memDcCapture, hrgn_foreground_);
|
||||
SelectObject(memDcCapture, GetStockObject(DC_BRUSH));
|
||||
SetDCBrushColor(memDcCapture, RGB(0xff, 0xff, 0));
|
||||
FillRect(memDcCapture, &rcScreen, (HBRUSH)GetStockObject(DC_BRUSH));
|
||||
|
||||
if (dcScreen) {
|
||||
ReleaseDC(NULL, dcScreen);
|
||||
}
|
||||
SelectObject(memDcCapture, bmpOriginCapture);
|
||||
DeleteDC(memDcCapture);
|
||||
}
|
||||
|
||||
// trigger event
|
||||
if (callback_) {
|
||||
callback_->OnCaptureCompleted(screen_capturer_proxy_.GetFrame().release());
|
||||
}
|
||||
}
|
||||
|
||||
void AppCapturerWin::UpdateRegions() {
|
||||
// List Windows of selected application
|
||||
EnumWindowsCtx lParamEnumWindows;
|
||||
lParamEnumWindows.process_id = processId_;
|
||||
lParamEnumWindows.list_all = true;
|
||||
EnumWindows(EnumWindowsProc, (LPARAM)&lParamEnumWindows);
|
||||
|
||||
SetRectRgn(hrgn_foreground_, 0, 0, 0, 0);
|
||||
SetRectRgn(hrgn_visual_, 0, 0, 0, 0);
|
||||
SetRectRgn(hrgn_background_, 0, 0, 0, 0);
|
||||
|
||||
HRGN hrgn_screen_ = CreateRectRgn(0, 0,
|
||||
GetSystemMetrics(SM_CXVIRTUALSCREEN),
|
||||
GetSystemMetrics(SM_CYVIRTUALSCREEN));
|
||||
|
||||
HRGN hrgn_window = CreateRectRgn(0, 0, 0, 0);
|
||||
HRGN hrgn_internsect = CreateRectRgn(0, 0, 0, 0);
|
||||
std::vector<WindowItem>::reverse_iterator itItem;
|
||||
for (itItem = lParamEnumWindows.windows.rbegin(); itItem != lParamEnumWindows.windows.rend(); itItem++) {
|
||||
WindowItem window_item = *itItem;
|
||||
SetRectRgn(hrgn_window, 0, 0, 0, 0);
|
||||
if (GetWindowRgn(window_item.handle, hrgn_window) == ERROR) {
|
||||
SetRectRgn(hrgn_window, window_item.bounds.left,
|
||||
window_item.bounds.top,
|
||||
window_item.bounds.right,
|
||||
window_item.bounds.bottom);
|
||||
}
|
||||
|
||||
if (window_item.owned) {
|
||||
CombineRgn(hrgn_visual_, hrgn_visual_, hrgn_window, RGN_OR);
|
||||
CombineRgn(hrgn_foreground_, hrgn_foreground_, hrgn_window, RGN_DIFF);
|
||||
} else {
|
||||
SetRectRgn(hrgn_internsect, 0, 0, 0, 0);
|
||||
CombineRgn(hrgn_internsect, hrgn_visual_, hrgn_window, RGN_AND);
|
||||
|
||||
CombineRgn(hrgn_visual_, hrgn_visual_, hrgn_internsect, RGN_DIFF);
|
||||
|
||||
CombineRgn(hrgn_foreground_, hrgn_foreground_, hrgn_internsect, RGN_OR);
|
||||
}
|
||||
}
|
||||
CombineRgn(hrgn_background_, hrgn_screen_, hrgn_visual_, RGN_DIFF);
|
||||
|
||||
if (hrgn_window) {
|
||||
DeleteObject(hrgn_window);
|
||||
}
|
||||
if (hrgn_internsect) {
|
||||
DeleteObject(hrgn_internsect);
|
||||
}
|
||||
// Not implemented yet: See Bug 1036653
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
AppCapturer* AppCapturer::Create(const DesktopCaptureOptions& options) {
|
||||
return new AppCapturerWin(options);
|
||||
return new AppCapturerWin();
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
|
@ -149,8 +149,6 @@
|
|||
"win/scoped_gdi_object.h",
|
||||
"win/scoped_thread_desktop.cc",
|
||||
"win/scoped_thread_desktop.h",
|
||||
"win/win_shared.h",
|
||||
"win/win_shared.cc",
|
||||
"win/desktop_device_info_win.h",
|
||||
"win/desktop_device_info_win.cc",
|
||||
"window_capturer_win.cc",
|
||||
|
|
|
@ -3,18 +3,8 @@
|
|||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "webrtc/modules/desktop_capture/win/desktop_device_info_win.h"
|
||||
#include "webrtc/modules/desktop_capture/win/win_shared.h"
|
||||
#include <stdio.h>
|
||||
|
||||
// Duplicating declaration so that it always resolves in decltype use
|
||||
// typedef BOOL (WINAPI *QueryFullProcessImageNameProc)(HANDLE hProcess, DWORD dwFlags, LPTSTR lpExeName, PDWORD lpdwSize);
|
||||
BOOL WINAPI QueryFullProcessImageName(HANDLE hProcess, DWORD dwFlags, LPTSTR lpExeName, PDWORD lpdwSize);
|
||||
|
||||
// Duplicating declaration so that it always resolves in decltype use
|
||||
// typedoef DWORD (WINAPI *GetProcessImageFileNameProc)(HANDLE hProcess, LPTSTR lpImageFileName, DWORD nSize);
|
||||
DWORD WINAPI GetProcessImageFileName(HANDLE hProcess, LPTSTR lpImageFileName, DWORD nSize);
|
||||
|
||||
namespace webrtc {
|
||||
namespace webrtc{
|
||||
|
||||
DesktopDeviceInfo * DesktopDeviceInfoImpl::Create() {
|
||||
DesktopDeviceInfoWin * pDesktopDeviceInfo = new DesktopDeviceInfoWin();
|
||||
|
@ -32,7 +22,7 @@ DesktopDeviceInfoWin::~DesktopDeviceInfoWin() {
|
|||
}
|
||||
|
||||
#if !defined(MULTI_MONITOR_SCREENSHARE)
|
||||
void DesktopDeviceInfoWin::MultiMonitorScreenshare()
|
||||
int32_t DesktopDeviceInfoWin::MultiMonitorScreenshare()
|
||||
{
|
||||
DesktopDisplayDevice *pDesktopDeviceInfo = new DesktopDisplayDevice;
|
||||
if (pDesktopDeviceInfo) {
|
||||
|
@ -42,86 +32,35 @@ void DesktopDeviceInfoWin::MultiMonitorScreenshare()
|
|||
|
||||
desktop_display_list_[pDesktopDeviceInfo->getScreenId()] = pDesktopDeviceInfo;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void DesktopDeviceInfoWin::InitializeScreenList() {
|
||||
int32_t DesktopDeviceInfoWin::Init() {
|
||||
#if !defined(MULTI_MONITOR_SCREENSHARE)
|
||||
MultiMonitorScreenshare();
|
||||
#endif
|
||||
|
||||
initializeWindowList();
|
||||
|
||||
return 0;
|
||||
}
|
||||
void DesktopDeviceInfoWin::InitializeApplicationList() {
|
||||
// List all running applications exclude background process.
|
||||
HWND hWnd;
|
||||
for (hWnd = GetWindow(GetDesktopWindow(), GW_CHILD); hWnd; hWnd = GetWindow(hWnd, GW_HWNDNEXT)) {
|
||||
if (!IsWindowVisible(hWnd))
|
||||
continue;
|
||||
|
||||
DWORD dwProcessId = 0;
|
||||
GetWindowThreadProcessId(hWnd, &dwProcessId);
|
||||
|
||||
// filter out non-process, current process, or any already seen processes
|
||||
if (dwProcessId == 0 || dwProcessId == GetCurrentProcessId() ||
|
||||
desktop_application_list_.find(dwProcessId) != desktop_application_list_.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add one application
|
||||
DesktopApplication *pDesktopApplication = new DesktopApplication;
|
||||
if (!pDesktopApplication) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// process id
|
||||
pDesktopApplication->setProcessId(dwProcessId);
|
||||
|
||||
// process path name
|
||||
WCHAR szFilePathName[MAX_PATH]={0};
|
||||
decltype(QueryFullProcessImageName) *lpfnQueryFullProcessImageNameProc =
|
||||
reinterpret_cast<decltype(QueryFullProcessImageName) *>(GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "QueryFullProcessImageNameW"));
|
||||
if (lpfnQueryFullProcessImageNameProc) {
|
||||
// After Vista
|
||||
DWORD dwMaxSize = _MAX_PATH;
|
||||
HANDLE hWndPro = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwProcessId);
|
||||
if(hWndPro) {
|
||||
lpfnQueryFullProcessImageNameProc(hWndPro, 0, szFilePathName, &dwMaxSize);
|
||||
CloseHandle(hWndPro);
|
||||
}
|
||||
} else {
|
||||
HMODULE hModPSAPI = LoadLibrary(TEXT("PSAPI.dll"));
|
||||
if (hModPSAPI) {
|
||||
decltype(GetProcessImageFileName) *pfnGetProcessImageFileName =
|
||||
reinterpret_cast<decltype(GetProcessImageFileName) *>(GetProcAddress(hModPSAPI, "GetProcessImageFileNameW"));
|
||||
|
||||
if (pfnGetProcessImageFileName) {
|
||||
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, dwProcessId);
|
||||
if (hProcess) {
|
||||
DWORD dwMaxSize = _MAX_PATH;
|
||||
pfnGetProcessImageFileName(hProcess, szFilePathName, dwMaxSize);
|
||||
CloseHandle(hProcess);
|
||||
}
|
||||
}
|
||||
FreeLibrary(hModPSAPI);
|
||||
}
|
||||
}
|
||||
pDesktopApplication->setProcessPathName(Utf16ToUtf8(szFilePathName).c_str());
|
||||
|
||||
// application name
|
||||
WCHAR szWndTitle[_MAX_PATH]={0};
|
||||
GetWindowText(hWnd, szWndTitle, MAX_PATH);
|
||||
if (lstrlen(szWndTitle) <= 0) {
|
||||
pDesktopApplication->setProcessAppName(Utf16ToUtf8(szFilePathName).c_str());
|
||||
} else {
|
||||
pDesktopApplication->setProcessAppName(Utf16ToUtf8(szWndTitle).c_str());
|
||||
}
|
||||
|
||||
// unique id name
|
||||
char idStr[64];
|
||||
_snprintf_s(idStr, sizeof(idStr), sizeof(idStr) - 1, "%ld", pDesktopApplication->getProcessId());
|
||||
pDesktopApplication->setUniqueIdName(idStr);
|
||||
|
||||
desktop_application_list_[pDesktopApplication->getProcessId()] = pDesktopApplication;
|
||||
int32_t DesktopDeviceInfoWin::Refresh() {
|
||||
#if !defined(MULTI_MONITOR_SCREENSHARE)
|
||||
std::map<intptr_t,DesktopDisplayDevice*>::iterator iterDevice;
|
||||
for (iterDevice=desktop_display_list_.begin(); iterDevice!=desktop_display_list_.end(); iterDevice++){
|
||||
DesktopDisplayDevice * pDesktopDisplayDevice = iterDevice->second;
|
||||
delete pDesktopDisplayDevice;
|
||||
iterDevice->second = NULL;
|
||||
}
|
||||
desktop_display_list_.clear();
|
||||
MultiMonitorScreenshare();
|
||||
#endif
|
||||
|
||||
RefreshWindowList();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
} //namespace webrtc
|
||||
|
|
|
@ -15,14 +15,13 @@ public:
|
|||
DesktopDeviceInfoWin();
|
||||
~DesktopDeviceInfoWin();
|
||||
|
||||
protected:
|
||||
//DesktopDeviceInfo Interfaces
|
||||
virtual void InitializeApplicationList() OVERRIDE;
|
||||
virtual void InitializeScreenList() OVERRIDE;
|
||||
virtual int32_t Init();
|
||||
virtual int32_t Refresh();
|
||||
|
||||
private:
|
||||
#if !defined(MULTI_MONITOR_SCREENSHARE)
|
||||
void MultiMonitorScreenshare();
|
||||
int32_t MultiMonitorScreenshare();
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <windows.h>
|
||||
#include "webrtc/modules/desktop_capture/win/win_shared.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
std::string Utf16ToUtf8(const WCHAR* str) {
|
||||
int len_utf8 = WideCharToMultiByte(CP_UTF8, 0, str, -1,
|
||||
NULL, 0, NULL, NULL);
|
||||
if (len_utf8 <= 0) {
|
||||
return std::string();
|
||||
}
|
||||
std::string result(len_utf8, '\0');
|
||||
int rv = WideCharToMultiByte(CP_UTF8, 0, str, -1,
|
||||
&*(result.begin()), len_utf8,
|
||||
NULL, NULL);
|
||||
if (rv != len_utf8) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
};
|
|
@ -1,12 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
std::string Utf16ToUtf8(const WCHAR* str);
|
||||
|
||||
};
|
Загрузка…
Ссылка в новой задаче