2025-11-28 00:35:46 +09:00

314 lines
6.8 KiB
C++

/******************************Module*Header*******************************\
* Module Name: display.cpp
*
* Support for DDraw device on Multiple Monitors.
*
*
* Created: Mon 01/24/2000
* Author: Stephen Estrop [StEstrop]
* Mod: KirtD - First integration into MF renderer model
*
* Copyright (c) Microsoft Corporation
\**************************************************************************/
#include <windows.h>
#include <unknwn.h>
#include "display.h"
#include <strsafe.h>
#ifndef DEFAULT_DENSITY_LIMIT
#define DEFAULT_DENSITY_LIMIT 60
#endif
#ifndef WIDTH
#define WIDTH(x) ((x)->right - (x)->left)
#endif
#ifndef HEIGHT
#define HEIGHT(x) ((x)->bottom - (x)->top)
#endif
/* -------------------------------------------------------------------------
** Structure use to pass info to the DDrawEnumEx callback
** -------------------------------------------------------------------------
*/
struct DDRAWINFO
{
DWORD dwCount;
DWORD dwPmiSize;
HRESULT hrCallback;
const GUID* pGUID;
CAMDDrawMonitorInfo* pmi;
HWND hwnd;
};
/******************************Public*Routine******************************\
* TermDDrawMonitorInfo
*
*
*
* History:
* 01-17-2000 - StEstrop - Created
*
\**************************************************************************/
void CMonitorArray::TermDDrawMonitorInfo(
_Inout_ CAMDDrawMonitorInfo* pmi
)
{
ZeroMemory(pmi, sizeof(CAMDDrawMonitorInfo));
}
/*****************************Private*Routine******************************\
* GetAMDDrawMonitorInfo
*
*
*
* History:
* Tue 08/17/1999 - StEstrop - Created
*
\**************************************************************************/
BOOL CMonitorArray::GetAMDDrawMonitorInfo(
UINT uDevID,
_Out_ CAMDDrawMonitorInfo* lpmi,
_In_ HMONITOR hm
)
{
MONITORINFOEX miInfoEx;
miInfoEx.cbSize = sizeof(miInfoEx);
lpmi->hMon = NULL;
lpmi->uDevID = 0;
lpmi->physMonDim.cx = 0;
lpmi->physMonDim.cy = 0;
lpmi->dwRefreshRate = DEFAULT_DENSITY_LIMIT;
if (GetMonitorInfo(hm, &miInfoEx))
{
HRESULT hr = StringCchCopy(lpmi->szDevice, sizeof(lpmi->szDevice)/sizeof(lpmi->szDevice[0]), miInfoEx.szDevice);
if ( FAILED( hr ) )
{
return FALSE;
}
lpmi->hMon = hm;
lpmi->uDevID = uDevID;
lpmi->physMonDim.cx = WIDTH(&miInfoEx.rcMonitor);
lpmi->physMonDim.cy = HEIGHT(&miInfoEx.rcMonitor);
int j = 0;
DISPLAY_DEVICE ddMonitor;
ddMonitor.cb = sizeof(ddMonitor);
while (EnumDisplayDevices(lpmi->szDevice, j, &ddMonitor, 0))
{
if (ddMonitor.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)
{
DEVMODE dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
if (EnumDisplaySettings(lpmi->szDevice, ENUM_CURRENT_SETTINGS, &dm))
{
lpmi->dwRefreshRate = dm.dmDisplayFrequency == 0 ? lpmi->dwRefreshRate : dm.dmDisplayFrequency;
}
// Remove registry snooping for monitor dimensions, as this is not supported by LDDM.
// if (!FindMonitorDimensions(ddMonitor.DeviceID, &lpmi->physMonDim.cx, &lpmi->physMonDim.cy))
{
lpmi->physMonDim.cx = WIDTH(&miInfoEx.rcMonitor);
lpmi->physMonDim.cy = HEIGHT(&miInfoEx.rcMonitor);
}
}
j++;
}
return TRUE;
}
return FALSE;
}
BOOL CMonitorArray::InitMonitor(
_In_ HMONITOR hMon,
BOOL fXclMode
)
{
if (GetAMDDrawMonitorInfo(m_dwNumMonitors, &m_DDMon[m_dwNumMonitors], hMon))
{
m_DDMon[m_dwNumMonitors].pDD = (IUnknown*)1; // make checks for pDD succeed.
m_dwNumMonitors++;
}
if (EVR_MAX_MONITORS >= m_dwNumMonitors)
{
// don't exceed array bounds
return TRUE;
}
return FALSE;
}
BOOL CALLBACK CMonitorArray::MonitorEnumProc(
_In_ HMONITOR hMon,
_In_opt_ HDC hDC,
_In_ LPRECT pRect,
LPARAM dwData
)
{
MonitorEnumProcInfo* info = (MonitorEnumProcInfo*)dwData;
if (!info)
{
return TRUE;
}
return info->pMonArray->InitMonitor(hMon, FALSE);
}
/*****************************Private*Routine******************************\
* InitializeDisplaySystem
*
*
*
* History:
* Mon 01/24/2000 - StEstrop - Created
*
\**************************************************************************/
HRESULT CMonitorArray::InitializeDisplaySystem(
_In_ HWND hwnd
)
{
HRESULT hr = S_OK;
MonitorEnumProcInfo info;
info.hwnd = hwnd;
info.pMonArray = this;
EnumDisplayMonitors(NULL, NULL, &MonitorEnumProc, (LPARAM)&info);
if (m_dwNumMonitors == 0)
{
hr = HRESULT_FROM_WIN32(GetLastError());
return(hr);
}
return(hr);
}
/*****************************Private*Routine******************************\
* FindMonitor
*
* find the current monitor
*
* History:
* Fri 04/25/2000 - GlennE - Created
*
\**************************************************************************/
CAMDDrawMonitorInfo* CMonitorArray::FindMonitor(
_In_ HMONITOR hMon
)
{
for (DWORD i = 0; i < m_dwNumMonitors; i++)
{
if (hMon == m_DDMon[i].hMon)
{
return &m_DDMon[i];
}
}
return NULL;
}
/*****************************Private*Routine******************************\
* MatchGUID
*
*
*
* History:
* Fri 04/25/2000 - GlennE - Created
*
\**************************************************************************/
HRESULT CMonitorArray::MatchGUID(
UINT uDevID,
_Out_ DWORD* pdwMatchID
)
{
HRESULT hr = S_OK;
*pdwMatchID = 0;
for (DWORD i = 0; i < m_dwNumMonitors; i++)
{
UINT uMonDevID = m_DDMon[i].uDevID;
if (uDevID == uMonDevID)
{
*pdwMatchID = i;
hr = S_OK;
return( hr );
}
}
hr = S_FALSE;
return( hr );
}
/*****************************Private*Routine******************************\
* TerminateDisplaySystem
*
*
*
* History:
* Mon 01/24/2000 - StEstrop - Created
*
\**************************************************************************/
void CMonitorArray::TerminateDisplaySystem()
{
for (DWORD i = 0; i < m_dwNumMonitors; i++)
{
TermDDrawMonitorInfo(&m_DDMon[i]);
}
m_dwNumMonitors = 0;
}
/******************************Public*Routine******************************\
* Constructor and destructor
*
*
*
* History:
* Fri 11/17/2001 - StEstrop - Created
*
\**************************************************************************/
CMonitorArray::CMonitorArray()
: m_dwNumMonitors(0)
{
ZeroMemory(m_DDMon, sizeof(m_DDMon));
}
CMonitorArray::~CMonitorArray()
{
TerminateDisplaySystem();
}