/* * Copyright (c) 2010-2020 Belledonne Communications SARL. * * This file is part of linphone-desktop * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "DesktopToolsWindows.hpp" #include "config.h" #include #include #include #include // ============================================================================= DesktopTools::DesktopTools(QObject *parent) : QObject(parent) { } DesktopTools::~DesktopTools() { setScreenSaverStatus(true); } bool DesktopTools::getScreenSaverStatus() const { return mScreenSaverStatus; } void DesktopTools::setScreenSaverStatus(bool status) { if (status == mScreenSaverStatus) return; if (status) SetThreadExecutionState(ES_CONTINUOUS); else SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED); mScreenSaverStatus = status; emit screenSaverStatusChanged(status); } //----------- Get Windows void getWindowMap(HWND hwnd, LPARAM lParam) { const DWORD TITLE_SIZE = 1024; WCHAR windowTitle[TITLE_SIZE]; GetWindowTextW(hwnd, windowTitle, TITLE_SIZE); std::wstring title(&windowTitle[0]); int length = ::GetWindowTextLength(hwnd); if (!IsWindowVisible(hwnd) || length == 0) { return; } QList &windowsMap = *reinterpret_cast *>(lParam); QVariantMap windowMap; windowMap["name"] = QString::fromStdWString(title); windowMap["windowId"] = (quint64)hwnd; windowsMap << windowMap; } BOOL CALLBACK getChildWindowsCb(HWND hwnd, LPARAM lParam) { getWindowMap(hwnd, lParam); return TRUE; } BOOL CALLBACK getWindowsCb(HWND hwnd, LPARAM lParam) { getWindowMap(hwnd, lParam); // EnumChildWindows(hwnd, getChildWindowsCb, lParam); return TRUE; } QList DesktopTools::getWindows() { #ifdef ENABLE_SCREENSHARING QList windowsMap; EnumWindows(getWindowsCb, reinterpret_cast(&windowsMap)); return windowsMap; #else return QList(); #endif } //----------------------------------------------------------- #ifndef GCL_HICON #define GCL_HICON -14 #endif QImage DesktopTools::getWindowIcon(void *window) { #ifdef ENABLE_SCREENSHARING HICON icon = (HICON)GetClassLongPtr((HWND)window, GCL_HICON); #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QPixmap pixmap = QtWin::fromHICON(icon); return pixmap.toImage(); #else return QImage::fromHICON(icon); #endif #else return QImage(); #endif } QImage DesktopTools::takeScreenshot(void *window) { QImage image; #ifdef ENABLE_SCREENSHARING RECT rect = {0}; if (!GetWindowRect((HWND)window, &rect)) { qCritical() << "[DesktopTools] Cannot get window size"; return image; } HDC hDC = GetDC((HWND)window); if (hDC == NULL) { qCritical() << "[DesktopTools] GetDC failed."; return image; } HDC hTargetDC = CreateCompatibleDC(hDC); if (hTargetDC == NULL) { ReleaseDC((HWND)window, hDC); qCritical() << "[DesktopTools] CreateCompatibleDC failed."; return image; } HBITMAP hBitmap = CreateCompatibleBitmap(hDC, rect.right - rect.left, rect.bottom - rect.top); if (hBitmap == NULL) { ReleaseDC((HWND)window, hDC); ReleaseDC((HWND)window, hTargetDC); qCritical() << "[DesktopTools] CreateCompatibleBitmap failed."; return image; } if (!SelectObject(hTargetDC, hBitmap)) { DeleteObject(hBitmap); ReleaseDC((HWND)window, hDC); ReleaseDC((HWND)window, hTargetDC); qCritical() << "[DesktopTools] SelectObject failed."; return image; } if (!PrintWindow((HWND)window, hTargetDC, PW_RENDERFULLCONTENT)) { DeleteObject(hBitmap); ReleaseDC((HWND)window, hDC); ReleaseDC((HWND)window, hTargetDC); qCritical() << "[DesktopTools] PrintWindow failed."; return image; } #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QPixmap pixmap = QtWin::fromHBITMAP(hBitmap); image = pixmap.toImage(); #else image = QImage::fromHBITMAP(hBitmap); #endif DeleteObject(hBitmap); ReleaseDC((HWND)window, hDC); ReleaseDC((HWND)window, hTargetDC); #endif return image; } uintptr_t DesktopTools::getDisplayIndex(void *screenSharing) { Q_UNUSED(screenSharing) #ifdef ENABLE_SCREENSHARING return *(uintptr_t *)(&screenSharing); #else return NULL; #endif } QRect DesktopTools::getWindowGeometry(void *screenSharing) { Q_UNUSED(screenSharing) QRect result; #ifdef ENABLE_SCREENSHARING HWND windowId = *(HWND *)&screenSharing; RECT area; if (S_OK == DwmGetWindowAttribute(windowId, DWMWA_EXTENDED_FRAME_BOUNDS, &area, sizeof(RECT))) { result = QRect(area.left + 1, area.top, area.right - area.left, area.bottom - area.top); // +1 for border } else qWarning() << "Cannot get attributes from HWND: " << windowId; #endif return result; }