BsWin32VideoModeInfo.cpp 3.1 KB

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