Separate projection mode from rest of touch HUD
[chromium-blink-merge.git] / ash / display / display_info.cc
bloba1770001c82488a23ef8075ef6ebdbefffd3a64d
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <stdio.h>
6 #include <string>
7 #include <vector>
9 #include "ash/display/display_info.h"
10 #include "base/logging.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/stringprintf.h"
14 #include "ui/gfx/display.h"
15 #include "ui/gfx/size_conversions.h"
16 #include "ui/gfx/size_f.h"
18 #if defined(OS_WIN)
19 #include "ui/aura/root_window_host.h"
20 #endif
22 namespace ash {
23 namespace internal {
25 // satic
26 DisplayInfo DisplayInfo::CreateFromSpec(const std::string& spec) {
27 return CreateFromSpecWithID(spec, gfx::Display::kInvalidDisplayID);
30 // static
31 DisplayInfo DisplayInfo::CreateFromSpecWithID(const std::string& spec,
32 int64 id) {
33 // Default bounds for a display.
34 const int kDefaultHostWindowX = 200;
35 const int kDefaultHostWindowY = 200;
36 const int kDefaultHostWindowWidth = 1366;
37 const int kDefaultHostWindowHeight = 768;
39 // Use larger than max int to catch overflow early.
40 static int64 synthesized_display_id = 2200000000LL;
42 #if defined(OS_WIN)
43 gfx::Rect bounds_in_pixel(aura::RootWindowHost::GetNativeScreenSize());
44 #else
45 gfx::Rect bounds_in_pixel(kDefaultHostWindowX, kDefaultHostWindowY,
46 kDefaultHostWindowWidth, kDefaultHostWindowHeight);
47 #endif
48 std::string main_spec = spec;
50 float ui_scale = 1.0f;
51 std::vector<std::string> parts;
52 if (Tokenize(main_spec, "@", &parts) == 2) {
53 double scale_in_double = 0;
54 if (base::StringToDouble(parts[1], &scale_in_double))
55 ui_scale = scale_in_double;
56 main_spec = parts[0];
59 size_t count = Tokenize(main_spec, "/", &parts);
60 gfx::Display::Rotation rotation(gfx::Display::ROTATE_0);
61 bool has_overscan = false;
62 if (count) {
63 main_spec = parts[0];
64 if (count >= 2) {
65 std::string options = parts[1];
66 for (size_t i = 0; i < options.size(); ++i) {
67 char c = options[i];
68 switch (c) {
69 case 'o':
70 has_overscan = true;
71 break;
72 case 'r': // rotate 90 degrees to 'right'.
73 rotation = gfx::Display::ROTATE_90;
74 break;
75 case 'u': // 180 degrees, 'u'pside-down.
76 rotation = gfx::Display::ROTATE_180;
77 break;
78 case 'l': // rotate 90 degrees to 'left'.
79 rotation = gfx::Display::ROTATE_270;
80 break;
86 int x = 0, y = 0, width, height;
87 float device_scale_factor = 1.0f;
88 if (sscanf(main_spec.c_str(), "%dx%d*%f",
89 &width, &height, &device_scale_factor) >= 2 ||
90 sscanf(main_spec.c_str(), "%d+%d-%dx%d*%f", &x, &y, &width, &height,
91 &device_scale_factor) >= 4) {
92 bounds_in_pixel.SetRect(x, y, width, height);
94 if (id == gfx::Display::kInvalidDisplayID)
95 id = synthesized_display_id++;
96 DisplayInfo display_info(
97 id, base::StringPrintf("Display-%d", static_cast<int>(id)), has_overscan);
98 display_info.set_device_scale_factor(device_scale_factor);
99 display_info.set_rotation(rotation);
100 display_info.set_ui_scale(ui_scale);
101 display_info.SetBounds(bounds_in_pixel);
103 // To test the overscan, it creates the default 5% overscan.
104 if (has_overscan) {
105 int width = bounds_in_pixel.width() / device_scale_factor / 40;
106 int height = bounds_in_pixel.height() / device_scale_factor / 40;
107 display_info.SetOverscanInsets(gfx::Insets(height, width, height, width));
108 display_info.UpdateDisplaySize();
111 DVLOG(1) << "DisplayInfoFromSpec info=" << display_info.ToString()
112 << ", spec=" << spec;
113 return display_info;
116 DisplayInfo::DisplayInfo()
117 : id_(gfx::Display::kInvalidDisplayID),
118 has_overscan_(false),
119 rotation_(gfx::Display::ROTATE_0),
120 device_scale_factor_(1.0f),
121 overscan_insets_in_dip_(0, 0, 0, 0),
122 ui_scale_(1.0f),
123 native_(false) {
126 DisplayInfo::DisplayInfo(int64 id,
127 const std::string& name,
128 bool has_overscan)
129 : id_(id),
130 name_(name),
131 has_overscan_(has_overscan),
132 rotation_(gfx::Display::ROTATE_0),
133 device_scale_factor_(1.0f),
134 overscan_insets_in_dip_(0, 0, 0, 0),
135 ui_scale_(1.0f),
136 native_(false) {
139 DisplayInfo::~DisplayInfo() {
142 void DisplayInfo::Copy(const DisplayInfo& native_info) {
143 DCHECK(id_ == native_info.id_);
144 name_ = native_info.name_;
145 has_overscan_ = native_info.has_overscan_;
147 DCHECK(!native_info.bounds_in_pixel_.IsEmpty());
148 bounds_in_pixel_ = native_info.bounds_in_pixel_;
149 size_in_pixel_ = native_info.size_in_pixel_;
150 device_scale_factor_ = native_info.device_scale_factor_;
152 // Copy overscan_insets_in_dip_ if it's not empty. This is for test
153 // cases which use "/o" annotation which sets the overscan inset
154 // to native, and that overscan has to be propagated. This does not
155 // happen on the real environment.
156 if (!native_info.overscan_insets_in_dip_.empty())
157 overscan_insets_in_dip_ = native_info.overscan_insets_in_dip_;
159 // Rotation_ and ui_scale_ are given by preference, or unit
160 // tests. Don't copy if this native_info came from
161 // DisplayChangeObserverX11.
162 if (!native_info.native()) {
163 rotation_ = native_info.rotation_;
164 ui_scale_ = native_info.ui_scale_;
166 // Don't copy insets as it may be given by preference. |rotation_|
167 // is treated as a native so that it can be specified in
168 // |CreateFromSpec|.
171 void DisplayInfo::SetBounds(const gfx::Rect& new_bounds_in_pixel) {
172 bounds_in_pixel_ = new_bounds_in_pixel;
173 size_in_pixel_ = new_bounds_in_pixel.size();
174 UpdateDisplaySize();
177 void DisplayInfo::UpdateDisplaySize() {
178 size_in_pixel_ = bounds_in_pixel_.size();
179 if (!overscan_insets_in_dip_.empty()) {
180 gfx::Insets insets_in_pixel =
181 overscan_insets_in_dip_.Scale(device_scale_factor_);
182 size_in_pixel_.Enlarge(-insets_in_pixel.width(), -insets_in_pixel.height());
183 } else {
184 overscan_insets_in_dip_.Set(0, 0, 0, 0);
187 if (rotation_ == gfx::Display::ROTATE_90 ||
188 rotation_ == gfx::Display::ROTATE_270)
189 size_in_pixel_.SetSize(size_in_pixel_.height(), size_in_pixel_.width());
190 gfx::SizeF size_f(size_in_pixel_);
191 size_f.Scale(ui_scale_);
192 size_in_pixel_ = gfx::ToFlooredSize(size_f);
195 void DisplayInfo::SetOverscanInsets(const gfx::Insets& insets_in_dip) {
196 overscan_insets_in_dip_ = insets_in_dip;
199 gfx::Insets DisplayInfo::GetOverscanInsetsInPixel() const {
200 return overscan_insets_in_dip_.Scale(device_scale_factor_);
203 std::string DisplayInfo::ToString() const {
204 int rotation_degree = static_cast<int>(rotation_) * 90;
205 return base::StringPrintf(
206 "DisplayInfo[%lld] bounds=%s, size=%s, scale=%f, "
207 "overscan=%s, rotation=%d, ui-scale=%f",
208 static_cast<long long int>(id_),
209 bounds_in_pixel_.ToString().c_str(),
210 size_in_pixel_.ToString().c_str(),
211 device_scale_factor_,
212 overscan_insets_in_dip_.ToString().c_str(),
213 rotation_degree,
214 ui_scale_);
217 } // namespace internal
218 } // namespace ash