BsWin32VideoModeInfo.cpp 3.2 KB

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