OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/host/desktop_resizer.h" | 5 #include "remoting/host/desktop_resizer.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 | 10 |
(...skipping 15 matching lines...) Expand all Loading... |
26 virtual SkISize GetCurrentSize() OVERRIDE; | 26 virtual SkISize GetCurrentSize() OVERRIDE; |
27 virtual std::list<SkISize> GetSupportedSizes( | 27 virtual std::list<SkISize> GetSupportedSizes( |
28 const SkISize& preferred) OVERRIDE; | 28 const SkISize& preferred) OVERRIDE; |
29 virtual void SetSize(const SkISize& size) OVERRIDE; | 29 virtual void SetSize(const SkISize& size) OVERRIDE; |
30 virtual void RestoreSize(const SkISize& original) OVERRIDE; | 30 virtual void RestoreSize(const SkISize& original) OVERRIDE; |
31 | 31 |
32 private: | 32 private: |
33 static bool IsResizeSupported(); | 33 static bool IsResizeSupported(); |
34 | 34 |
35 // Calls EnumDisplaySettingsEx() for the primary monitor. | 35 // Calls EnumDisplaySettingsEx() for the primary monitor. |
36 // Returns a DEVMODE with no fields if |mode_number| does not exist. | 36 // Returns false if |mode_number| does not exist. |
37 static bool GetPrimaryDisplayMode( | 37 static bool GetPrimaryDisplayMode( |
38 DWORD mode_number, DWORD flags, DEVMODE* mode); | 38 DWORD mode_number, DWORD flags, DEVMODE* mode); |
39 | 39 |
40 // Returns true if the mode has width, height, bits-per-pixel, frequency | 40 // Returns true if the mode has width, height, bits-per-pixel, frequency |
41 // and orientation fields. | 41 // and orientation fields. |
42 static bool IsModeValid(const DEVMODE& mode); | 42 static bool IsModeValid(const DEVMODE& mode); |
43 | 43 |
44 // Returns the width & height of |mode|, or 0x0 if they are missing. | 44 // Returns the width & height of |mode|, or 0x0 if they are missing. |
45 static SkISize GetModeSize(const DEVMODE& mode); | 45 static SkISize GetModeSize(const DEVMODE& mode); |
46 | 46 |
47 std::map<SkISize, DEVMODE> modes_; | 47 std::map<SkISize, DEVMODE> best_mode_for_size_; |
48 | 48 |
49 DISALLOW_COPY_AND_ASSIGN(DesktopResizerWin); | 49 DISALLOW_COPY_AND_ASSIGN(DesktopResizerWin); |
50 }; | 50 }; |
51 | 51 |
52 DesktopResizerWin::DesktopResizerWin() { | 52 DesktopResizerWin::DesktopResizerWin() { |
53 } | 53 } |
54 | 54 |
55 DesktopResizerWin::~DesktopResizerWin() { | 55 DesktopResizerWin::~DesktopResizerWin() { |
56 } | 56 } |
57 | 57 |
58 SkISize DesktopResizerWin::GetCurrentSize() { | 58 SkISize DesktopResizerWin::GetCurrentSize() { |
59 DEVMODE current_mode; | 59 DEVMODE current_mode; |
60 if (GetPrimaryDisplayMode(ENUM_CURRENT_SETTINGS, 0, ¤t_mode) && | 60 if (GetPrimaryDisplayMode(ENUM_CURRENT_SETTINGS, 0, ¤t_mode) && |
61 IsModeValid(current_mode)) | 61 IsModeValid(current_mode)) |
62 return GetModeSize(current_mode); | 62 return GetModeSize(current_mode); |
63 return SkISize::Make(0, 0); | 63 return SkISize::Make(0, 0); |
64 } | 64 } |
65 | 65 |
66 std::list<SkISize> DesktopResizerWin::GetSupportedSizes( | 66 std::list<SkISize> DesktopResizerWin::GetSupportedSizes( |
67 const SkISize& preferred) { | 67 const SkISize& preferred) { |
68 if (!IsResizeSupported()) | 68 if (!IsResizeSupported()) |
69 return std::list<SkISize>(); | 69 return std::list<SkISize>(); |
70 | 70 |
71 // Enumerate the sizes to return, and where there are multiple modes of | 71 // Enumerate the sizes to return, and where there are multiple modes of |
72 // the same size, store the one most closely matching the current mode | 72 // the same size, store the one most closely matching the current mode |
73 // in |modes_|. | 73 // in |best_mode_for_size_|. |
74 DEVMODE current_mode; | 74 DEVMODE current_mode; |
75 if (!GetPrimaryDisplayMode(ENUM_CURRENT_SETTINGS, 0, ¤t_mode) || | 75 if (!GetPrimaryDisplayMode(ENUM_CURRENT_SETTINGS, 0, ¤t_mode) || |
76 !IsModeValid(current_mode)) | 76 !IsModeValid(current_mode)) |
77 return std::list<SkISize>(); | 77 return std::list<SkISize>(); |
78 | 78 |
79 std::list<SkISize> sizes; | 79 std::list<SkISize> sizes; |
80 modes_.clear(); | 80 best_mode_for_size_.clear(); |
81 for (DWORD i = 0; ; ++i) { | 81 for (DWORD i = 0; ; ++i) { |
82 DEVMODE candidate_mode; | 82 DEVMODE candidate_mode; |
83 if (!GetPrimaryDisplayMode(i, EDS_ROTATEDMODE, &candidate_mode)) | 83 if (!GetPrimaryDisplayMode(i, EDS_ROTATEDMODE, &candidate_mode)) |
84 break; | 84 break; |
85 | 85 |
86 // Ignore modes missing the fields that we expect. | 86 // Ignore modes missing the fields that we expect. |
87 if (!IsModeValid(candidate_mode)) | 87 if (!IsModeValid(candidate_mode)) |
88 continue; | 88 continue; |
89 | 89 |
90 // Ignore modes with differing bits-per-pixel. | 90 // Ignore modes with differing bits-per-pixel. |
91 if (candidate_mode.dmBitsPerPel != current_mode.dmBitsPerPel) | 91 if (candidate_mode.dmBitsPerPel != current_mode.dmBitsPerPel) |
92 continue; | 92 continue; |
93 | 93 |
94 // If there is an existing mode of the same dimensions, prefer the | 94 // If there are multiple modes with the same dimensions: |
95 // one with the higher frequency. | 95 // - Prefer the modes which match the current rotation. |
| 96 // - Among those, prefer modes which match the current frequency. |
| 97 // - Otherwise, prefer modes with a higher frequency. |
96 SkISize candidate_size = GetModeSize(candidate_mode); | 98 SkISize candidate_size = GetModeSize(candidate_mode); |
97 if (modes_.count(candidate_size) != 0) { | 99 if (best_mode_for_size_.count(candidate_size) != 0) { |
98 DEVMODE existing_mode = modes_[candidate_size]; | 100 DEVMODE best_mode = best_mode_for_size_[candidate_size]; |
99 if (existing_mode.dmDisplayFrequency > | 101 |
100 candidate_mode.dmDisplayFrequency) | 102 if ((candidate_mode.dmDisplayOrientation != |
| 103 current_mode.dmDisplayOrientation) && |
| 104 (best_mode.dmDisplayOrientation == |
| 105 current_mode.dmDisplayOrientation)) { |
101 continue; | 106 continue; |
| 107 } |
| 108 |
| 109 if ((candidate_mode.dmDisplayFrequency != |
| 110 current_mode.dmDisplayFrequency) && |
| 111 (best_mode.dmDisplayFrequency >= |
| 112 candidate_mode.dmDisplayFrequency)) { |
| 113 continue; |
| 114 } |
102 } else { | 115 } else { |
103 // If we haven't seen this size before, add it to those we return. | 116 // If we haven't seen this size before, add it to those we return. |
104 sizes.push_back(candidate_size); | 117 sizes.push_back(candidate_size); |
105 } | 118 } |
106 | 119 |
107 modes_[candidate_size] = candidate_mode; | 120 best_mode_for_size_[candidate_size] = candidate_mode; |
108 } | 121 } |
109 | 122 |
110 return sizes; | 123 return sizes; |
111 } | 124 } |
112 | 125 |
113 void DesktopResizerWin::SetSize(const SkISize& size) { | 126 void DesktopResizerWin::SetSize(const SkISize& size) { |
114 if (modes_.count(size) == 0) | 127 if (best_mode_for_size_.count(size) == 0) |
115 return; | 128 return; |
116 | 129 |
117 DEVMODE new_mode = modes_[size]; | 130 DEVMODE new_mode = best_mode_for_size_[size]; |
118 DWORD result = ChangeDisplaySettings(&new_mode, CDS_FULLSCREEN); | 131 DWORD result = ChangeDisplaySettings(&new_mode, CDS_FULLSCREEN); |
119 if (result != DISP_CHANGE_SUCCESSFUL) | 132 if (result != DISP_CHANGE_SUCCESSFUL) |
120 LOG(ERROR) << "SetSize failed: " << result; | 133 LOG(ERROR) << "SetSize failed: " << result; |
121 } | 134 } |
122 | 135 |
123 void DesktopResizerWin::RestoreSize(const SkISize& original) { | 136 void DesktopResizerWin::RestoreSize(const SkISize& original) { |
124 // Restore the display mode based on the registry configuration. | 137 // Restore the display mode based on the registry configuration. |
125 DWORD result = ChangeDisplaySettings(NULL, 0); | 138 DWORD result = ChangeDisplaySettings(NULL, 0); |
126 if (result != DISP_CHANGE_SUCCESSFUL) | 139 if (result != DISP_CHANGE_SUCCESSFUL) |
127 LOG(ERROR) << "RestoreSize failed: " << result; | 140 LOG(ERROR) << "RestoreSize failed: " << result; |
(...skipping 27 matching lines...) Expand all Loading... |
155 SkISize DesktopResizerWin::GetModeSize(const DEVMODE& mode) { | 168 SkISize DesktopResizerWin::GetModeSize(const DEVMODE& mode) { |
156 DCHECK(IsModeValid(mode)); | 169 DCHECK(IsModeValid(mode)); |
157 return SkISize::Make(mode.dmPelsWidth, mode.dmPelsHeight); | 170 return SkISize::Make(mode.dmPelsWidth, mode.dmPelsHeight); |
158 } | 171 } |
159 | 172 |
160 scoped_ptr<DesktopResizer> DesktopResizer::Create() { | 173 scoped_ptr<DesktopResizer> DesktopResizer::Create() { |
161 return scoped_ptr<DesktopResizer>(new DesktopResizerWin); | 174 return scoped_ptr<DesktopResizer>(new DesktopResizerWin); |
162 } | 175 } |
163 | 176 |
164 } // namespace remoting | 177 } // namespace remoting |
OLD | NEW |