BsWin32VideoModeInfo.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #include "BsWin32VideoModeInfo.h"
  2. #include "BsMath.h"
  3. #include "BsException.h"
  4. namespace BansheeEngine
  5. {
  6. BOOL CALLBACK monitorEnumCallback(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM lParam)
  7. {
  8. Vector<HMONITOR>* outputInfos = (Vector<HMONITOR>*)lParam;
  9. outputInfos->push_back(hMonitor);
  10. return TRUE;
  11. };
  12. Win32VideoModeInfo::Win32VideoModeInfo()
  13. {
  14. Vector<HMONITOR> handles;
  15. EnumDisplayMonitors(0, nullptr, &monitorEnumCallback, (LPARAM)&handles);
  16. // Sort so that primary is the first output
  17. for (auto iter = handles.begin(); iter != handles.end(); ++iter)
  18. {
  19. MONITORINFOEX monitorInfo;
  20. memset(&monitorInfo, 0, sizeof(MONITORINFOEX));
  21. monitorInfo.cbSize = sizeof(MONITORINFOEX);
  22. GetMonitorInfo(*iter, &monitorInfo);
  23. if ((monitorInfo.dwFlags & MONITORINFOF_PRIMARY) != 0)
  24. {
  25. if (iter != handles.begin())
  26. {
  27. HMONITOR temp = handles[0];
  28. handles[0] = *iter;
  29. *iter = temp;
  30. }
  31. break;
  32. }
  33. }
  34. UINT32 idx = 0;
  35. for (auto& handle : handles)
  36. {
  37. mOutputs.push_back(bs_new<Win32VideoOutputInfo>(handle, idx++));
  38. }
  39. }
  40. Win32VideoOutputInfo::Win32VideoOutputInfo(HMONITOR monitorHandle, UINT32 outputIdx)
  41. :mMonitorHandle(monitorHandle)
  42. {
  43. MONITORINFOEX monitorInfo;
  44. memset(&monitorInfo, 0, sizeof(MONITORINFOEX));
  45. monitorInfo.cbSize = sizeof(MONITORINFOEX);
  46. GetMonitorInfo(mMonitorHandle, &monitorInfo);
  47. mName = monitorInfo.szDevice;
  48. DEVMODE devMode;
  49. devMode.dmSize = sizeof(DEVMODE);
  50. devMode.dmDriverExtra = 0;
  51. UINT32 i = 0;
  52. while (EnumDisplaySettings(monitorInfo.szDevice, i++, &devMode))
  53. {
  54. bool foundVideoMode = false;
  55. for (auto videoMode : mVideoModes)
  56. {
  57. Win32VideoMode* win32VideoMode = static_cast<Win32VideoMode*>(videoMode);
  58. UINT32 intRefresh = Math::roundToInt(win32VideoMode->mRefreshRate);
  59. if (win32VideoMode->mWidth == devMode.dmPelsWidth && win32VideoMode->mHeight == devMode.dmPelsHeight
  60. && intRefresh == devMode.dmDisplayFrequency)
  61. {
  62. foundVideoMode = true;
  63. break;
  64. }
  65. }
  66. if (!foundVideoMode)
  67. {
  68. Win32VideoMode* videoMode = bs_new<Win32VideoMode>(devMode.dmPelsWidth, devMode.dmPelsHeight,
  69. (float)devMode.dmDisplayFrequency, outputIdx);
  70. videoMode->mIsCustom = false;
  71. mVideoModes.push_back(videoMode);
  72. }
  73. }
  74. // Get desktop display mode
  75. EnumDisplaySettings(monitorInfo.szDevice, ENUM_CURRENT_SETTINGS, &devMode);
  76. Win32VideoMode* desktopVideoMode = bs_new<Win32VideoMode>(devMode.dmPelsWidth, devMode.dmPelsHeight,
  77. (float)devMode.dmDisplayFrequency, outputIdx);
  78. desktopVideoMode->mIsCustom = false;
  79. mDesktopVideoMode = desktopVideoMode;
  80. }
  81. Win32VideoOutputInfo::~Win32VideoOutputInfo()
  82. {
  83. CloseHandle(mMonitorHandle);
  84. }
  85. Win32VideoMode::Win32VideoMode(UINT32 width, UINT32 height, float refreshRate, UINT32 outputIdx)
  86. :VideoMode(width, height, refreshRate, outputIdx)
  87. { }
  88. }