Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

226 lines
4.7 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. IgnoreNoModeChange.cpp
  5. Abstract:
  6. Ignore mode changes that are not really different from the current mode.
  7. The problem is that even if there is no real mode change, the uniqueness
  8. value for the mode is still updated. DirectDraw checks this value every
  9. time it enters any API and if the mode uniqueness value has changed, it
  10. resets all it's objects.
  11. Applications will hit this if they call ChangeDisplaySettings* and don't
  12. realize that even if the mode is identical, they'll still have to reset
  13. all their objects.
  14. Notes:
  15. This is a general purpose shim.
  16. History:
  17. 01/20/2000 linstev Created
  18. --*/
  19. #include "precomp.h"
  20. IMPLEMENT_SHIM_BEGIN(IgnoreNoModeChange)
  21. #include "ShimHookMacro.h"
  22. APIHOOK_ENUM_BEGIN
  23. APIHOOK_ENUM_ENTRY(ChangeDisplaySettingsA)
  24. APIHOOK_ENUM_ENTRY(ChangeDisplaySettingsW)
  25. APIHOOK_ENUM_ENTRY(ChangeDisplaySettingsExA)
  26. APIHOOK_ENUM_ENTRY(ChangeDisplaySettingsExW)
  27. APIHOOK_ENUM_END
  28. BOOL
  29. IsModeEqual(
  30. DWORD dwWidth,
  31. DWORD dwHeight,
  32. DWORD dwBitsPerPel,
  33. DWORD dwRefresh
  34. )
  35. {
  36. BOOL bRet = FALSE;
  37. DEVMODEA dm;
  38. dm.dmSize = sizeof(DEVMODEA);
  39. //
  40. // Get the existing settings.
  41. //
  42. if (EnumDisplaySettingsA(0, ENUM_CURRENT_SETTINGS, &dm)) {
  43. //
  44. // Assume that 0 or 1 means default refresh.
  45. //
  46. if (dwRefresh <= 1) {
  47. dwRefresh = dm.dmDisplayFrequency;
  48. }
  49. bRet = (dwWidth == dm.dmPelsWidth) &&
  50. (dwHeight == dm.dmPelsHeight) &&
  51. (dwBitsPerPel == dm.dmBitsPerPel) &&
  52. (dwRefresh == dm.dmDisplayFrequency);
  53. }
  54. if (bRet) {
  55. LOGN(
  56. eDbgLevelInfo,
  57. "[IsModeEqual] Ignoring irrelevant mode change.");
  58. } else {
  59. LOGN(
  60. eDbgLevelInfo,
  61. "Mode change is required.");
  62. }
  63. return bRet;
  64. }
  65. /*++
  66. Force temporary change.
  67. --*/
  68. LONG
  69. APIHOOK(ChangeDisplaySettingsA)(
  70. LPDEVMODEA lpDevMode,
  71. DWORD dwFlags
  72. )
  73. {
  74. if (lpDevMode &&
  75. IsModeEqual(
  76. lpDevMode->dmPelsWidth,
  77. lpDevMode->dmPelsHeight,
  78. lpDevMode->dmBitsPerPel,
  79. lpDevMode->dmDisplayFrequency)) {
  80. return DISP_CHANGE_SUCCESSFUL;
  81. }
  82. return ORIGINAL_API(ChangeDisplaySettingsA)(
  83. lpDevMode,
  84. CDS_FULLSCREEN);
  85. }
  86. /*++
  87. Force temporary change.
  88. --*/
  89. LONG
  90. APIHOOK(ChangeDisplaySettingsW)(
  91. LPDEVMODEW lpDevMode,
  92. DWORD dwFlags
  93. )
  94. {
  95. if (lpDevMode &&
  96. IsModeEqual(
  97. lpDevMode->dmPelsWidth,
  98. lpDevMode->dmPelsHeight,
  99. lpDevMode->dmBitsPerPel,
  100. lpDevMode->dmDisplayFrequency)) {
  101. return DISP_CHANGE_SUCCESSFUL;
  102. }
  103. return ORIGINAL_API(ChangeDisplaySettingsW)(
  104. lpDevMode,
  105. CDS_FULLSCREEN);
  106. }
  107. /*++
  108. Force temporary change.
  109. --*/
  110. LONG
  111. APIHOOK(ChangeDisplaySettingsExA)(
  112. LPCSTR lpszDeviceName,
  113. LPDEVMODEA lpDevMode,
  114. HWND hwnd,
  115. DWORD dwflags,
  116. LPVOID lParam
  117. )
  118. {
  119. if (lpDevMode &&
  120. IsModeEqual(
  121. lpDevMode->dmPelsWidth,
  122. lpDevMode->dmPelsHeight,
  123. lpDevMode->dmBitsPerPel,
  124. lpDevMode->dmDisplayFrequency)) {
  125. return DISP_CHANGE_SUCCESSFUL;
  126. }
  127. return ORIGINAL_API(ChangeDisplaySettingsExA)(
  128. lpszDeviceName,
  129. lpDevMode,
  130. hwnd,
  131. CDS_FULLSCREEN,
  132. lParam);
  133. }
  134. /*++
  135. Force temporary change.
  136. --*/
  137. LONG
  138. APIHOOK(ChangeDisplaySettingsExW)(
  139. LPCWSTR lpszDeviceName,
  140. LPDEVMODEW lpDevMode,
  141. HWND hwnd,
  142. DWORD dwflags,
  143. LPVOID lParam
  144. )
  145. {
  146. if (lpDevMode &&
  147. IsModeEqual(
  148. lpDevMode->dmPelsWidth,
  149. lpDevMode->dmPelsHeight,
  150. lpDevMode->dmBitsPerPel,
  151. lpDevMode->dmDisplayFrequency)) {
  152. return DISP_CHANGE_SUCCESSFUL;
  153. }
  154. return ORIGINAL_API(ChangeDisplaySettingsExW)(
  155. lpszDeviceName,
  156. lpDevMode,
  157. hwnd,
  158. CDS_FULLSCREEN,
  159. lParam);
  160. }
  161. /*++
  162. Register hooked functions
  163. --*/
  164. HOOK_BEGIN
  165. APIHOOK_ENTRY(USER32.DLL, ChangeDisplaySettingsA)
  166. APIHOOK_ENTRY(USER32.DLL, ChangeDisplaySettingsW)
  167. APIHOOK_ENTRY(USER32.DLL, ChangeDisplaySettingsExA)
  168. APIHOOK_ENTRY(USER32.DLL, ChangeDisplaySettingsExW)
  169. HOOK_END
  170. IMPLEMENT_SHIM_END