Index: chrome/browser/ui/webui/options/chromeos/display_options_handler.cc |
diff --git a/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc |
index c84f034f8e0e45a5263a435a816a7a577ef5e463..f22e92c7d2c6e5034a2e5e40655bbee2bb24f5d9 100644 |
--- a/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc |
+++ b/chrome/browser/ui/webui/options/chromeos/display_options_handler.cc |
@@ -54,10 +54,33 @@ int64 GetDisplayId(const base::ListValue* args) { |
return display_id; |
} |
-bool CompareDisplayMode(ash::DisplayMode d1, ash::DisplayMode d2) { |
- if (d1.size.GetArea() == d2.size.GetArea()) |
- return d1.refresh_rate < d2.refresh_rate; |
- return d1.size.GetArea() < d2.size.GetArea(); |
+bool CompareResolution(base::Value* display1, base::Value* display2) { |
+ base::DictionaryValue* d1 = NULL; |
+ base::DictionaryValue* d2 = NULL; |
+ CHECK(display1->GetAsDictionary(&d1) && display2->GetAsDictionary(&d2)); |
+ int width1 = 0, height1 = 0, width2 = 0, height2 = 0; |
+ CHECK(d1->GetInteger("width", &width1) && d1->GetInteger("height", &height1)); |
+ CHECK(d2->GetInteger("width", &width2) && d2->GetInteger("height", &height2)); |
+ double scale_factor1 = 0, scale_factor2 = 0; |
+ if (d1->GetDouble("scaleFactor", &scale_factor1)) { |
+ width1 /= scale_factor1; |
+ height1 /= scale_factor1; |
+ } |
+ if (d2->GetDouble("scaleFactor", &scale_factor2)) { |
+ width2 /= scale_factor2; |
+ height2 /= scale_factor2; |
+ } |
+ |
+ if (width1 * height1 == width2 * height2) { |
+ if (scale_factor1 != scale_factor2) |
+ return scale_factor1 < scale_factor2; |
+ |
+ int refresh_rate1 = 0, refresh_rate2 = 0; |
+ CHECK(d1->GetInteger("refreshRate", &refresh_rate1) == |
+ d2->GetInteger("refreshRate", &refresh_rate2)); |
+ return refresh_rate1 < refresh_rate2; |
+ } |
+ return width1 * height1 < width2 * height2; |
} |
base::string16 GetColorProfileName(ui::ColorCalibrationProfile profile) { |
@@ -82,6 +105,82 @@ base::string16 GetColorProfileName(ui::ColorCalibrationProfile profile) { |
return base::string16(); |
} |
+scoped_ptr<base::ListValue> GetResolutionsForInternalDisplay( |
+ const ash::DisplayInfo& display_info) { |
+ scoped_ptr<base::ListValue> js_resolutions(new base::ListValue); |
+ const std::vector<float> ui_scales = |
+ DisplayManager::GetScalesForDisplay(display_info); |
+ gfx::SizeF base_size = display_info.bounds_in_native().size(); |
+ base_size.Scale(1.0f / display_info.device_scale_factor()); |
+ if (display_info.rotation() == gfx::Display::ROTATE_90 || |
+ display_info.rotation() == gfx::Display::ROTATE_270) { |
+ float tmp = base_size.width(); |
+ base_size.set_width(base_size.height()); |
+ base_size.set_height(tmp); |
+ } |
+ |
+ for (size_t i = 0; i < ui_scales.size(); ++i) { |
+ base::DictionaryValue* resolution_info = new base::DictionaryValue(); |
+ gfx::SizeF new_size = base_size; |
+ new_size.Scale(ui_scales[i]); |
+ gfx::Size resolution = gfx::ToFlooredSize(new_size); |
+ resolution_info->SetDouble("scale", ui_scales[i]); |
+ if (ui_scales[i] == 1.0f) |
+ resolution_info->SetBoolean("isBest", true); |
+ resolution_info->SetBoolean( |
+ "selected", display_info.configured_ui_scale() == ui_scales[i]); |
+ resolution_info->SetInteger("width", resolution.width()); |
+ resolution_info->SetInteger("height", resolution.height()); |
+ js_resolutions->Append(resolution_info); |
+ } |
+ |
+ return js_resolutions.Pass(); |
+} |
+ |
+scoped_ptr<base::ListValue> GetResolutionsForExternalDisplay( |
+ const ash::DisplayInfo& display_info) { |
+ scoped_ptr<base::ListValue> js_resolutions(new base::ListValue); |
+ |
+ gfx::Size current_size = display_info.bounds_in_native().size(); |
+ gfx::Insets current_overscan = display_info.GetOverscanInsetsInPixel(); |
+ int largest_index = -1; |
+ int largest_area = -1; |
+ |
+ for (size_t i = 0; i < display_info.display_modes().size(); ++i) { |
+ base::DictionaryValue* resolution_info = new base::DictionaryValue(); |
+ const ash::DisplayMode& display_mode = display_info.display_modes()[i]; |
+ gfx::Size resolution = display_mode.size; |
+ |
+ if (resolution.GetArea() > largest_area) { |
+ resolution_info->SetBoolean("isBest", true); |
+ largest_area = resolution.GetArea(); |
+ if (largest_index >= 0) { |
+ base::DictionaryValue* prev_largest = NULL; |
+ CHECK(js_resolutions->GetDictionary(largest_index, &prev_largest)); |
+ prev_largest->SetBoolean("isBest", false); |
+ } |
+ largest_index = i; |
+ } |
+ |
+ if (resolution == current_size) { |
+ // Right now, the scale factor for unselected resolutions is unknown. |
+ // TODO(mukai): Set the scale factor for unselected ones. |
+ resolution_info->SetDouble( |
+ "scaleFactor", display_info.device_scale_factor()); |
+ resolution_info->SetBoolean("selected", true); |
+ } |
+ |
+ resolution.Enlarge( |
+ -current_overscan.width(), -current_overscan.height()); |
+ resolution_info->SetInteger("width", resolution.width()); |
+ resolution_info->SetInteger("height", resolution.height()); |
+ resolution_info->SetDouble("refreshRate", display_mode.refresh_rate); |
+ js_resolutions->Append(resolution_info); |
+ } |
+ |
+ return js_resolutions.Pass(); |
+} |
+ |
} // namespace |
DisplayOptionsHandler::DisplayOptionsHandler() { |
@@ -217,60 +316,13 @@ void DisplayOptionsHandler::SendDisplayInfo( |
js_display->SetBoolean("isInternal", display.IsInternal()); |
js_display->SetInteger("orientation", |
static_cast<int>(display_info.rotation())); |
- std::vector<ash::DisplayMode> display_modes; |
- std::vector<float> ui_scales; |
- if (display.IsInternal()) { |
- ui_scales = DisplayManager::GetScalesForDisplay(display_info); |
- gfx::SizeF base_size = display_info.bounds_in_native().size(); |
- base_size.Scale(1.0f / display_info.device_scale_factor()); |
- if (display_info.rotation() == gfx::Display::ROTATE_90 || |
- display_info.rotation() == gfx::Display::ROTATE_270) { |
- float tmp = base_size.width(); |
- base_size.set_width(base_size.height()); |
- base_size.set_height(tmp); |
- } |
- for (size_t i = 0; i < ui_scales.size(); ++i) { |
- gfx::SizeF new_size = base_size; |
- new_size.Scale(ui_scales[i]); |
- display_modes.push_back(ash::DisplayMode( |
- gfx::ToFlooredSize(new_size), -1.0f, false, false)); |
- } |
- } else { |
- for (size_t i = 0; i < display_info.display_modes().size(); ++i) |
- display_modes.push_back(display_info.display_modes()[i]); |
- } |
- std::sort(display_modes.begin(), display_modes.end(), CompareDisplayMode); |
- |
- base::ListValue* js_resolutions = new base::ListValue(); |
- gfx::Size current_size = display_info.bounds_in_native().size(); |
- gfx::Insets current_overscan = display_info.GetOverscanInsetsInPixel(); |
- for (size_t i = 0; i < display_modes.size(); ++i) { |
- base::DictionaryValue* resolution_info = new base::DictionaryValue(); |
- gfx::Size resolution = display_modes[i].size; |
- if (!ui_scales.empty()) { |
- resolution_info->SetDouble("scale", ui_scales[i]); |
- if (ui_scales[i] == 1.0f) |
- resolution_info->SetBoolean("isBest", true); |
- resolution_info->SetBoolean( |
- "selected", display_info.configured_ui_scale() == ui_scales[i]); |
- } else { |
- // Picks the largest one as the "best", which is the last element |
- // because |display_modes| is sorted by its area. |
- if (i == display_modes.size() - 1) |
- resolution_info->SetBoolean("isBest", true); |
- resolution_info->SetBoolean("selected", (resolution == current_size)); |
- resolution.Enlarge( |
- -current_overscan.width(), -current_overscan.height()); |
- } |
- resolution_info->SetInteger("width", resolution.width()); |
- resolution_info->SetInteger("height", resolution.height()); |
- if (display_modes[i].refresh_rate > 0.0f) { |
- resolution_info->SetDouble("refreshRate", |
- display_modes[i].refresh_rate); |
- } |
- js_resolutions->Append(resolution_info); |
- } |
- js_display->Set("resolutions", js_resolutions); |
+ |
+ scoped_ptr<base::ListValue> js_resolutions = display.IsInternal() ? |
+ GetResolutionsForInternalDisplay(display_info) : |
+ GetResolutionsForExternalDisplay(display_info); |
+ std::sort( |
+ js_resolutions->begin(), js_resolutions->end(), CompareResolution); |
+ js_display->Set("resolutions", js_resolutions.release()); |
js_display->SetInteger("colorProfile", display_info.color_profile()); |
base::ListValue* available_color_profiles = new base::ListValue(); |