Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(320)

Side by Side Diff: trunk/src/ui/views/widget/desktop_aura/desktop_screen_x11.cc

Issue 24365012: Revert 225054 "linux_aura: Implement most of DesktopScreenX11." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "ui/views/widget/desktop_aura/desktop_screen_x11.h" 5 #include "ui/views/widget/desktop_aura/desktop_screen.h"
6 6
7 #include <X11/extensions/Xrandr.h>
8 #include <X11/Xlib.h> 7 #include <X11/Xlib.h>
9 8
10 // It clashes with out RootWindow. 9 // It clashes with out RootWindow.
11 #undef RootWindow 10 #undef RootWindow
12 11
13 #include "base/logging.h" 12 #include "base/logging.h"
14 #include "base/x11/edid_parser_x11.h"
15 #include "ui/aura/root_window.h" 13 #include "ui/aura/root_window.h"
16 #include "ui/aura/root_window_host.h" 14 #include "ui/aura/root_window_host.h"
17 #include "ui/base/x/x11_util.h"
18 #include "ui/gfx/display.h" 15 #include "ui/gfx/display.h"
19 #include "ui/gfx/display_observer.h"
20 #include "ui/gfx/native_widget_types.h" 16 #include "ui/gfx/native_widget_types.h"
21 #include "ui/gfx/screen.h" 17 #include "ui/gfx/screen.h"
22 #include "ui/gfx/x/x11_types.h" 18 #include "ui/gfx/x/x11_types.h"
23 #include "ui/views/widget/desktop_aura/desktop_screen.h"
24 19
25 namespace { 20 namespace {
26 21
27 // The delay to perform configuration after RRNotify. See the comment 22 // TODO(erg): This method is a temporary hack, until we can reliably extract
28 // in |Dispatch()|. 23 // location data out of XRandR.
29 const int64 kConfigureDelayMs = 500; 24 gfx::Size GetPrimaryDisplaySize() {
30
31 std::vector<gfx::Display> GetFallbackDisplayList() {
32 ::XDisplay* display = gfx::GetXDisplay(); 25 ::XDisplay* display = gfx::GetXDisplay();
33 ::Screen* screen = DefaultScreenOfDisplay(display); 26 ::Screen* screen = DefaultScreenOfDisplay(display);
34 int width = WidthOfScreen(screen); 27 int width = WidthOfScreen(screen);
35 int height = HeightOfScreen(screen); 28 int height = HeightOfScreen(screen);
36 29
37 return std::vector<gfx::Display>( 30 return gfx::Size(width, height);
38 1, gfx::Display(0, gfx::Rect(0, 0, width, height)));
39 } 31 }
40 32
41 } // namespace 33 class DesktopScreenX11 : public gfx::Screen {
34 public:
35 DesktopScreenX11();
36 virtual ~DesktopScreenX11();
42 37
43 namespace views { 38 // Overridden from gfx::Screen:
39 virtual bool IsDIPEnabled() OVERRIDE;
40 virtual gfx::Point GetCursorScreenPoint() OVERRIDE;
41 virtual gfx::NativeWindow GetWindowUnderCursor() OVERRIDE;
42 virtual gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point)
43 OVERRIDE;
44 virtual int GetNumDisplays() const OVERRIDE;
45 virtual std::vector<gfx::Display> GetAllDisplays() const OVERRIDE;
46 virtual gfx::Display GetDisplayNearestWindow(
47 gfx::NativeView window) const OVERRIDE;
48 virtual gfx::Display GetDisplayNearestPoint(
49 const gfx::Point& point) const OVERRIDE;
50 virtual gfx::Display GetDisplayMatching(
51 const gfx::Rect& match_rect) const OVERRIDE;
52 virtual gfx::Display GetPrimaryDisplay() const OVERRIDE;
53 virtual void AddObserver(gfx::DisplayObserver* observer) OVERRIDE;
54 virtual void RemoveObserver(gfx::DisplayObserver* observer) OVERRIDE;
55
56 private:
57 DISALLOW_COPY_AND_ASSIGN(DesktopScreenX11);
58 };
44 59
45 //////////////////////////////////////////////////////////////////////////////// 60 ////////////////////////////////////////////////////////////////////////////////
46 // DesktopScreenX11, public: 61 // DesktopScreenX11, public:
47 62
48 DesktopScreenX11::DesktopScreenX11() 63 DesktopScreenX11::DesktopScreenX11() {
49 : xdisplay_(base::MessagePumpX11::GetDefaultXDisplay()),
50 x_root_window_(DefaultRootWindow(xdisplay_)),
51 has_xrandr_(false),
52 xrandr_event_base_(0) {
53 // We only support 1.3+. There were library changes before this and we should
54 // use the new interface instead of the 1.2 one.
55 int randr_version_major = 0;
56 int randr_version_minor = 0;
57 has_xrandr_ = XRRQueryVersion(
58 xdisplay_, &randr_version_major, &randr_version_minor) &&
59 randr_version_major == 1 &&
60 randr_version_minor >= 3;
61
62 if (has_xrandr_) {
63 int error_base_ignored = 0;
64 XRRQueryExtension(xdisplay_, &xrandr_event_base_, &error_base_ignored);
65
66 base::MessagePumpX11::Current()->AddDispatcherForRootWindow(this);
67 XRRSelectInput(xdisplay_,
68 x_root_window_,
69 RRScreenChangeNotifyMask | RROutputChangeNotifyMask);
70
71 displays_ = BuildDisplaysFromXRandRInfo();
72 } else {
73 displays_ = GetFallbackDisplayList();
74 }
75 } 64 }
76 65
77 DesktopScreenX11::~DesktopScreenX11() { 66 DesktopScreenX11::~DesktopScreenX11() {
78 if (has_xrandr_)
79 base::MessagePumpX11::Current()->RemoveDispatcherForRootWindow(this);
80 }
81
82 void DesktopScreenX11::ProcessDisplayChange(
83 const std::vector<gfx::Display>& incoming) {
84 std::vector<gfx::Display>::const_iterator cur_it = displays_.begin();
85 for (; cur_it != displays_.end(); ++cur_it) {
86 bool found = false;
87 for (std::vector<gfx::Display>::const_iterator incoming_it =
88 incoming.begin(); incoming_it != incoming.end(); ++incoming_it) {
89 if (cur_it->id() == incoming_it->id()) {
90 found = true;
91 break;
92 }
93 }
94
95 if (!found) {
96 FOR_EACH_OBSERVER(gfx::DisplayObserver, observer_list_,
97 OnDisplayRemoved(*cur_it));
98 }
99 }
100
101 std::vector<gfx::Display>::const_iterator incoming_it = incoming.begin();
102 for (; incoming_it != incoming.end(); ++incoming_it) {
103 bool found = false;
104 for (std::vector<gfx::Display>::const_iterator cur_it = displays_.begin();
105 cur_it != displays_.end(); ++cur_it) {
106 if (incoming_it->id() == cur_it->id()) {
107 if (incoming_it->bounds() != cur_it->bounds()) {
108 FOR_EACH_OBSERVER(gfx::DisplayObserver, observer_list_,
109 OnDisplayBoundsChanged(*incoming_it));
110 }
111
112 found = true;
113 break;
114 }
115 }
116
117 if (!found) {
118 FOR_EACH_OBSERVER(gfx::DisplayObserver, observer_list_,
119 OnDisplayAdded(*incoming_it));
120 }
121 }
122
123 displays_ = incoming;
124 } 67 }
125 68
126 //////////////////////////////////////////////////////////////////////////////// 69 ////////////////////////////////////////////////////////////////////////////////
127 // DesktopScreenX11, gfx::Screen implementation: 70 // DesktopScreenX11, gfx::Screen implementation:
128 71
129 bool DesktopScreenX11::IsDIPEnabled() { 72 bool DesktopScreenX11::IsDIPEnabled() {
130 return false; 73 return false;
131 } 74 }
132 75
133 gfx::Point DesktopScreenX11::GetCursorScreenPoint() { 76 gfx::Point DesktopScreenX11::GetCursorScreenPoint() {
134 XDisplay* display = gfx::GetXDisplay(); 77 XDisplay* display = gfx::GetXDisplay();
135 78
136 ::Window root, child; 79 ::Window root, child;
137 int root_x, root_y, win_x, win_y; 80 int root_x, root_y, win_x, win_y;
138 unsigned int mask; 81 unsigned int mask;
139 XQueryPointer(display, 82 XQueryPointer(display,
140 DefaultRootWindow(display), 83 DefaultRootWindow(display),
141 &root, 84 &root,
142 &child, 85 &child,
143 &root_x, 86 &root_x,
144 &root_y, 87 &root_y,
145 &win_x, 88 &win_x,
146 &win_y, 89 &win_y,
147 &mask); 90 &mask);
148 91
149 return gfx::Point(root_x, root_y); 92 return gfx::Point(root_x, root_y);
150 } 93 }
151 94
152 gfx::NativeWindow DesktopScreenX11::GetWindowUnderCursor() { 95 gfx::NativeWindow DesktopScreenX11::GetWindowUnderCursor() {
153 return GetWindowAtScreenPoint(GetCursorScreenPoint()); 96 // TODO(erg): Implement using the discussion at
97 // http://codereview.chromium.org/10279005/
98 return NULL;
154 } 99 }
155 100
156 gfx::NativeWindow DesktopScreenX11::GetWindowAtScreenPoint( 101 gfx::NativeWindow DesktopScreenX11::GetWindowAtScreenPoint(
157 const gfx::Point& point) { 102 const gfx::Point& point) {
158 // TODO(erg): Implement using the discussion at
159 // http://codereview.chromium.org/10279005/
160 NOTIMPLEMENTED(); 103 NOTIMPLEMENTED();
161 return NULL; 104 return NULL;
162 } 105 }
163 106
164 int DesktopScreenX11::GetNumDisplays() const { 107 int DesktopScreenX11::GetNumDisplays() const {
165 return displays_.size(); 108 // TODO(erg): Figure this out with oshima or piman because I have no clue
109 // about the XRandR implications here.
110 return 1;
166 } 111 }
167 112
168 std::vector<gfx::Display> DesktopScreenX11::GetAllDisplays() const { 113 std::vector<gfx::Display> DesktopScreenX11::GetAllDisplays() const {
169 return displays_; 114 // TODO(erg): Do the right thing once we know what that is.
115 return std::vector<gfx::Display>(1, GetPrimaryDisplay());
170 } 116 }
171 117
172 gfx::Display DesktopScreenX11::GetDisplayNearestWindow( 118 gfx::Display DesktopScreenX11::GetDisplayNearestWindow(
173 gfx::NativeView window) const { 119 gfx::NativeView window) const {
174 // TODO(erg): This should theoretically be easy, but it isn't. At the time we 120 // TODO(erg): Do the right thing once we know what that is.
175 // get called here, our aura::Window has not been Init()ed, because this 121 return gfx::Display(0, gfx::Rect(GetPrimaryDisplaySize()));
176 // method is called to get the device scale factor as part of
177 // RootWindow::Init(), before Window::Init(). This seems very confused; we're
178 // trying to get a display nearest window even before we've allocated the
179 // root window. Once fixed, the correct implementation should probably be:
180 //
181 // return GetDisplayMatching(window->GetBoundsInScreen());
182 //
183 // But at least for now, we'll just fallback:
184 return GetPrimaryDisplay();
185 } 122 }
186 123
187 gfx::Display DesktopScreenX11::GetDisplayNearestPoint( 124 gfx::Display DesktopScreenX11::GetDisplayNearestPoint(
188 const gfx::Point& point) const { 125 const gfx::Point& point) const {
189 for (std::vector<gfx::Display>::const_iterator it = displays_.begin(); 126 // TODO(erg): Do the right thing once we know what that is.
190 it != displays_.end(); ++it) { 127 return gfx::Display(0, gfx::Rect(GetPrimaryDisplaySize()));
191 if (it->bounds().Contains(point))
192 return *it;
193 }
194
195 return GetPrimaryDisplay();
196 } 128 }
197 129
198 gfx::Display DesktopScreenX11::GetDisplayMatching( 130 gfx::Display DesktopScreenX11::GetDisplayMatching(
199 const gfx::Rect& match_rect) const { 131 const gfx::Rect& match_rect) const {
200 int max_area = 0; 132 // TODO(erg): Do the right thing once we know what that is.
201 const gfx::Display* matching = NULL; 133 return gfx::Display(0, gfx::Rect(GetPrimaryDisplaySize()));
202 for (std::vector<gfx::Display>::const_iterator it = displays_.begin();
203 it != displays_.end(); ++it) {
204 gfx::Rect intersect = gfx::IntersectRects(it->bounds(), match_rect);
205 int area = intersect.width() * intersect.height();
206 if (area > max_area) {
207 max_area = area;
208 matching = &*it;
209 }
210 }
211 // Fallback to the primary display if there is no matching display.
212 return matching ? *matching : GetPrimaryDisplay();
213 } 134 }
214 135
215 gfx::Display DesktopScreenX11::GetPrimaryDisplay() const { 136 gfx::Display DesktopScreenX11::GetPrimaryDisplay() const {
216 return displays_.front(); 137 // TODO(erg): Do the right thing once we know what that is.
138 return gfx::Display(0, gfx::Rect(GetPrimaryDisplaySize()));
217 } 139 }
218 140
219 void DesktopScreenX11::AddObserver(gfx::DisplayObserver* observer) { 141 void DesktopScreenX11::AddObserver(gfx::DisplayObserver* observer) {
220 observer_list_.AddObserver(observer); 142 // TODO(erg|oshima): Do the right thing once we know what that is.
143 // crbug.com/122863
144 }
145 void DesktopScreenX11::RemoveObserver(gfx::DisplayObserver* observer) {
146 // TODO(erg|oshima): Do the right thing once we know what that is.
147 // crbug.com/122863
221 } 148 }
222 149
223 void DesktopScreenX11::RemoveObserver(gfx::DisplayObserver* observer) { 150 } // namespace
224 observer_list_.RemoveObserver(observer);
225 }
226
227 bool DesktopScreenX11::Dispatch(const base::NativeEvent& event) {
228 if (event->type - xrandr_event_base_ == RRScreenChangeNotify) {
229 // Pass the event through to xlib.
230 XRRUpdateConfiguration(event);
231 } else if (event->type - xrandr_event_base_ == RRNotify) {
232 // There's some sort of observer dispatch going on here, but I don't think
233 // it's the screen's?
234 DLOG(ERROR) << "DesktopScreenX11::Dispatch() -> RRNotify";
235
236 if (configure_timer_.get()) {
237 configure_timer_->Reset();
238 } else {
239 configure_timer_.reset(new base::OneShotTimer<DesktopScreenX11>());
240 configure_timer_->Start(
241 FROM_HERE,
242 base::TimeDelta::FromMilliseconds(kConfigureDelayMs),
243 this,
244 &DesktopScreenX11::ConfigureTimerFired);
245 }
246 }
247
248 return true;
249 }
250 151
251 //////////////////////////////////////////////////////////////////////////////// 152 ////////////////////////////////////////////////////////////////////////////////
252 // DesktopScreenX11, private:
253 153
254 DesktopScreenX11::DesktopScreenX11( 154 namespace views {
255 const std::vector<gfx::Display>& test_displays)
256 : xdisplay_(base::MessagePumpX11::GetDefaultXDisplay()),
257 x_root_window_(DefaultRootWindow(xdisplay_)),
258 has_xrandr_(false),
259 xrandr_event_base_(0),
260 displays_(test_displays) {
261 }
262
263 std::vector<gfx::Display> DesktopScreenX11::BuildDisplaysFromXRandRInfo() {
264 std::vector<gfx::Display> displays;
265 XRRScreenResources* resources =
266 XRRGetScreenResourcesCurrent(xdisplay_, x_root_window_);
267 if (!resources) {
268 LOG(ERROR) << "XRandR returned no displays. Falling back to Root Window.";
269 return GetFallbackDisplayList();
270 }
271
272 bool has_work_area = false;
273 gfx::Rect work_area;
274 std::vector<int> value;
275 if (ui::GetIntArrayProperty(x_root_window_, "_NET_WORKAREA", &value) &&
276 value.size() >= 4) {
277 work_area = gfx::Rect(value[0], value[1], value[2], value[3]);
278 has_work_area = true;
279 }
280
281 for (int i = 0; i < resources->noutput; ++i) {
282 RROutput output_id = resources->outputs[i];
283 XRROutputInfo* output_info =
284 XRRGetOutputInfo(xdisplay_, resources, output_id);
285
286 bool is_connected = (output_info->connection == RR_Connected);
287 if (!is_connected) {
288 XRRFreeOutputInfo(output_info);
289 continue;
290 }
291
292 if (output_info->crtc) {
293 XRRCrtcInfo *crtc = XRRGetCrtcInfo(xdisplay_,
294 resources,
295 output_info->crtc);
296
297 int64 display_id = -1;
298 if (!base::GetDisplayId(output_id, i, &display_id)) {
299 // It isn't ideal, but if we can't parse the EDID data, fallback on the
300 // display number.
301 display_id = i;
302 }
303
304 gfx::Rect crtc_bounds(crtc->x, crtc->y, crtc->width, crtc->height);
305 gfx::Display display(display_id, crtc_bounds);
306 if (has_work_area) {
307 gfx::Rect intersection = crtc_bounds;
308 intersection.Intersect(work_area);
309 display.set_work_area(intersection);
310 }
311
312 displays.push_back(display);
313
314 XRRFreeCrtcInfo(crtc);
315 }
316
317 XRRFreeOutputInfo(output_info);
318 }
319
320 XRRFreeScreenResources(resources);
321
322 if (displays.empty())
323 return GetFallbackDisplayList();
324
325 return displays;
326 }
327
328 void DesktopScreenX11::ConfigureTimerFired() {
329 std::vector<gfx::Display> new_displays = BuildDisplaysFromXRandRInfo();
330 ProcessDisplayChange(new_displays);
331 }
332
333 ////////////////////////////////////////////////////////////////////////////////
334 155
335 gfx::Screen* CreateDesktopScreen() { 156 gfx::Screen* CreateDesktopScreen() {
336 return new DesktopScreenX11; 157 return new DesktopScreenX11;
337 } 158 }
338 159
339 } // namespace views 160 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698