| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/display/manager/chromeos/x11/native_display_delegate_x11.h" | 5 #include "ui/display/manager/chromeos/x11/native_display_delegate_x11.h" |
| 6 | 6 |
| 7 #include <X11/Xatom.h> | 7 #include <X11/Xatom.h> |
| 8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
| 9 #include <X11/extensions/dpms.h> | 9 #include <X11/extensions/dpms.h> |
| 10 #include <X11/extensions/XInput2.h> | 10 #include <X11/extensions/XInput2.h> |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 platform_event_dispatcher_.reset(new NativeDisplayEventDispatcherX11( | 125 platform_event_dispatcher_.reset(new NativeDisplayEventDispatcherX11( |
| 126 helper_delegate_.get(), xrandr_event_base)); | 126 helper_delegate_.get(), xrandr_event_base)); |
| 127 | 127 |
| 128 if (ui::PlatformEventSource::GetInstance()) { | 128 if (ui::PlatformEventSource::GetInstance()) { |
| 129 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher( | 129 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher( |
| 130 platform_event_dispatcher_.get()); | 130 platform_event_dispatcher_.get()); |
| 131 } | 131 } |
| 132 } | 132 } |
| 133 | 133 |
| 134 void NativeDisplayDelegateX11::GrabServer() { | 134 void NativeDisplayDelegateX11::GrabServer() { |
| 135 CHECK(!screen_) << "Server already grabbed"; | 135 // Server already grabbed |
| 136 CHECK(!screen_); |
| 136 XGrabServer(display_); | 137 XGrabServer(display_); |
| 137 screen_.reset(XRRGetScreenResources(display_, window_)); | 138 screen_.reset(XRRGetScreenResources(display_, window_)); |
| 138 CHECK(screen_); | 139 CHECK(screen_); |
| 139 } | 140 } |
| 140 | 141 |
| 141 void NativeDisplayDelegateX11::UngrabServer() { | 142 void NativeDisplayDelegateX11::UngrabServer() { |
| 142 CHECK(screen_) << "Server not grabbed"; | 143 // Server not grabbed |
| 144 CHECK(screen_); |
| 143 screen_.reset(); | 145 screen_.reset(); |
| 144 XUngrabServer(display_); | 146 XUngrabServer(display_); |
| 145 // crbug.com/366125 | 147 // crbug.com/366125 |
| 146 XFlush(display_); | 148 XFlush(display_); |
| 147 } | 149 } |
| 148 | 150 |
| 149 void NativeDisplayDelegateX11::TakeDisplayControl( | 151 void NativeDisplayDelegateX11::TakeDisplayControl( |
| 150 const DisplayControlCallback& callback) { | 152 const DisplayControlCallback& callback) { |
| 151 NOTIMPLEMENTED(); | 153 NOTIMPLEMENTED(); |
| 152 } | 154 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 164 background_color_argb_ = color_argb; | 166 background_color_argb_ = color_argb; |
| 165 } | 167 } |
| 166 | 168 |
| 167 void NativeDisplayDelegateX11::ForceDPMSOn() { | 169 void NativeDisplayDelegateX11::ForceDPMSOn() { |
| 168 CHECK(DPMSEnable(display_)); | 170 CHECK(DPMSEnable(display_)); |
| 169 CHECK(DPMSForceLevel(display_, DPMSModeOn)); | 171 CHECK(DPMSForceLevel(display_, DPMSModeOn)); |
| 170 } | 172 } |
| 171 | 173 |
| 172 void NativeDisplayDelegateX11::GetDisplays( | 174 void NativeDisplayDelegateX11::GetDisplays( |
| 173 const GetDisplaysCallback& callback) { | 175 const GetDisplaysCallback& callback) { |
| 174 CHECK(screen_) << "Server not grabbed"; | 176 // Server not grabbed |
| 177 CHECK(screen_); |
| 175 | 178 |
| 176 cached_outputs_.clear(); | 179 cached_outputs_.clear(); |
| 177 std::set<RRCrtc> last_used_crtcs; | 180 std::set<RRCrtc> last_used_crtcs; |
| 178 | 181 |
| 179 InitModes(); | 182 InitModes(); |
| 180 for (int i = 0; i < screen_->noutput; ++i) { | 183 for (int i = 0; i < screen_->noutput; ++i) { |
| 181 RROutput output_id = screen_->outputs[i]; | 184 RROutput output_id = screen_->outputs[i]; |
| 182 XRROutputInfo* output_info = | 185 XRROutputInfo* output_info = |
| 183 XRRGetOutputInfo(display_, screen_.get(), output_id); | 186 XRRGetOutputInfo(display_, screen_.get(), output_id); |
| 184 if (output_info->connection == RR_Connected) { | 187 if (output_info->connection == RR_Connected) { |
| 185 DisplaySnapshotX11* output = | 188 DisplaySnapshotX11* output = |
| 186 InitDisplaySnapshot(output_id, output_info, &last_used_crtcs, i); | 189 InitDisplaySnapshot(output_id, output_info, &last_used_crtcs, i); |
| 187 cached_outputs_.push_back(output); | 190 cached_outputs_.push_back(output); |
| 188 } | 191 } |
| 189 XRRFreeOutputInfo(output_info); | 192 XRRFreeOutputInfo(output_info); |
| 190 } | 193 } |
| 191 | 194 |
| 192 callback.Run(cached_outputs_.get()); | 195 callback.Run(cached_outputs_.get()); |
| 193 } | 196 } |
| 194 | 197 |
| 195 void NativeDisplayDelegateX11::AddMode(const DisplaySnapshot& output, | 198 void NativeDisplayDelegateX11::AddMode(const DisplaySnapshot& output, |
| 196 const DisplayMode* mode) { | 199 const DisplayMode* mode) { |
| 197 CHECK(screen_) << "Server not grabbed"; | 200 // Server not grabbed |
| 198 CHECK(mode) << "Must add valid mode"; | 201 CHECK(screen_); |
| 202 // Must add valid mode |
| 203 CHECK(mode); |
| 199 | 204 |
| 200 const DisplaySnapshotX11& x11_output = | 205 const DisplaySnapshotX11& x11_output = |
| 201 static_cast<const DisplaySnapshotX11&>(output); | 206 static_cast<const DisplaySnapshotX11&>(output); |
| 202 RRMode mode_id = static_cast<const DisplayModeX11*>(mode)->mode_id(); | 207 RRMode mode_id = static_cast<const DisplayModeX11*>(mode)->mode_id(); |
| 203 | 208 |
| 204 VLOG(1) << "AddDisplayMode: output=" << x11_output.output() | 209 VLOG(1) << "AddDisplayMode: output=" << x11_output.output() |
| 205 << " mode=" << mode_id; | 210 << " mode=" << mode_id; |
| 206 XRRAddOutputMode(display_, x11_output.output(), mode_id); | 211 XRRAddOutputMode(display_, x11_output.output(), mode_id); |
| 207 } | 212 } |
| 208 | 213 |
| 209 void NativeDisplayDelegateX11::Configure(const DisplaySnapshot& output, | 214 void NativeDisplayDelegateX11::Configure(const DisplaySnapshot& output, |
| 210 const DisplayMode* mode, | 215 const DisplayMode* mode, |
| 211 const gfx::Point& origin, | 216 const gfx::Point& origin, |
| 212 const ConfigureCallback& callback) { | 217 const ConfigureCallback& callback) { |
| 213 const DisplaySnapshotX11& x11_output = | 218 const DisplaySnapshotX11& x11_output = |
| 214 static_cast<const DisplaySnapshotX11&>(output); | 219 static_cast<const DisplaySnapshotX11&>(output); |
| 215 RRMode mode_id = None; | 220 RRMode mode_id = None; |
| 216 if (mode) | 221 if (mode) |
| 217 mode_id = static_cast<const DisplayModeX11*>(mode)->mode_id(); | 222 mode_id = static_cast<const DisplayModeX11*>(mode)->mode_id(); |
| 218 | 223 |
| 219 callback.Run(ConfigureCrtc(x11_output.crtc(), mode_id, x11_output.output(), | 224 callback.Run(ConfigureCrtc(x11_output.crtc(), mode_id, x11_output.output(), |
| 220 origin.x(), origin.y())); | 225 origin.x(), origin.y())); |
| 221 } | 226 } |
| 222 | 227 |
| 223 bool NativeDisplayDelegateX11::ConfigureCrtc(RRCrtc crtc, | 228 bool NativeDisplayDelegateX11::ConfigureCrtc(RRCrtc crtc, |
| 224 RRMode mode, | 229 RRMode mode, |
| 225 RROutput output, | 230 RROutput output, |
| 226 int x, | 231 int x, |
| 227 int y) { | 232 int y) { |
| 228 CHECK(screen_) << "Server not grabbed"; | 233 // Server not grabbed |
| 234 CHECK(screen_); |
| 229 VLOG(1) << "ConfigureCrtc: crtc=" << crtc << " mode=" << mode | 235 VLOG(1) << "ConfigureCrtc: crtc=" << crtc << " mode=" << mode |
| 230 << " output=" << output << " x=" << x << " y=" << y; | 236 << " output=" << output << " x=" << x << " y=" << y; |
| 231 // Xrandr.h is full of lies. XRRSetCrtcConfig() is defined as returning a | 237 // Xrandr.h is full of lies. XRRSetCrtcConfig() is defined as returning a |
| 232 // Status, which is typically 0 for failure and 1 for success. In | 238 // Status, which is typically 0 for failure and 1 for success. In |
| 233 // actuality it returns a RRCONFIGSTATUS, which uses 0 for success. | 239 // actuality it returns a RRCONFIGSTATUS, which uses 0 for success. |
| 234 if (XRRSetCrtcConfig(display_, screen_.get(), crtc, CurrentTime, x, y, mode, | 240 if (XRRSetCrtcConfig(display_, screen_.get(), crtc, CurrentTime, x, y, mode, |
| 235 RR_Rotate_0, (output && mode) ? &output : NULL, | 241 RR_Rotate_0, (output && mode) ? &output : NULL, |
| 236 (output && mode) ? 1 : 0) != RRSetConfigSuccess) { | 242 (output && mode) ? 1 : 0) != RRSetConfigSuccess) { |
| 237 LOG(WARNING) << "Unable to configure CRTC " << crtc << ":" | 243 LOG(WARNING) << "Unable to configure CRTC " << crtc << ":" |
| 238 << " mode=" << mode << " output=" << output << " x=" << x | 244 << " mode=" << mode << " output=" << output << " x=" << x |
| 239 << " y=" << y; | 245 << " y=" << y; |
| 240 return false; | 246 return false; |
| 241 } | 247 } |
| 242 | 248 |
| 243 return true; | 249 return true; |
| 244 } | 250 } |
| 245 | 251 |
| 246 void NativeDisplayDelegateX11::CreateFrameBuffer(const gfx::Size& size) { | 252 void NativeDisplayDelegateX11::CreateFrameBuffer(const gfx::Size& size) { |
| 247 CHECK(screen_) << "Server not grabbed"; | 253 // Server not grabbed |
| 254 CHECK(screen_); |
| 248 gfx::Size current_screen_size( | 255 gfx::Size current_screen_size( |
| 249 DisplayWidth(display_, DefaultScreen(display_)), | 256 DisplayWidth(display_, DefaultScreen(display_)), |
| 250 DisplayHeight(display_, DefaultScreen(display_))); | 257 DisplayHeight(display_, DefaultScreen(display_))); |
| 251 | 258 |
| 252 VLOG(1) << "CreateFrameBuffer: new=" << size.ToString() | 259 VLOG(1) << "CreateFrameBuffer: new=" << size.ToString() |
| 253 << " current=" << current_screen_size.ToString(); | 260 << " current=" << current_screen_size.ToString(); |
| 254 | 261 |
| 255 DestroyUnusedCrtcs(); | 262 DestroyUnusedCrtcs(); |
| 256 | 263 |
| 257 if (size == current_screen_size) | 264 if (size == current_screen_size) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 281 void NativeDisplayDelegateX11::RemoveObserver(NativeDisplayObserver* observer) { | 288 void NativeDisplayDelegateX11::RemoveObserver(NativeDisplayObserver* observer) { |
| 282 observers_.RemoveObserver(observer); | 289 observers_.RemoveObserver(observer); |
| 283 } | 290 } |
| 284 | 291 |
| 285 display::FakeDisplayController* | 292 display::FakeDisplayController* |
| 286 NativeDisplayDelegateX11::GetFakeDisplayController() { | 293 NativeDisplayDelegateX11::GetFakeDisplayController() { |
| 287 return nullptr; | 294 return nullptr; |
| 288 } | 295 } |
| 289 | 296 |
| 290 void NativeDisplayDelegateX11::InitModes() { | 297 void NativeDisplayDelegateX11::InitModes() { |
| 291 CHECK(screen_) << "Server not grabbed"; | 298 // Server not grabbed |
| 299 CHECK(screen_); |
| 292 | 300 |
| 293 modes_.clear(); | 301 modes_.clear(); |
| 294 | 302 |
| 295 for (int i = 0; i < screen_->nmode; ++i) { | 303 for (int i = 0; i < screen_->nmode; ++i) { |
| 296 const XRRModeInfo& info = screen_->modes[i]; | 304 const XRRModeInfo& info = screen_->modes[i]; |
| 297 float refresh_rate = 0.0f; | 305 float refresh_rate = 0.0f; |
| 298 if (info.hTotal && info.vTotal) { | 306 if (info.hTotal && info.vTotal) { |
| 299 refresh_rate = | 307 refresh_rate = |
| 300 static_cast<float>(info.dotClock) / | 308 static_cast<float>(info.dotClock) / |
| 301 (static_cast<float>(info.hTotal) * static_cast<float>(info.vTotal)); | 309 (static_cast<float>(info.hTotal) * static_cast<float>(info.vTotal)); |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 display_, output_id, name, XA_ATOM, 32, PropModeReplace, data, 1); | 491 display_, output_id, name, XA_ATOM, 32, PropModeReplace, data, 1); |
| 484 if (err_tracker.FoundNewError()) { | 492 if (err_tracker.FoundNewError()) { |
| 485 LOG(ERROR) << "XRRChangeOutputProperty failed"; | 493 LOG(ERROR) << "XRRChangeOutputProperty failed"; |
| 486 return false; | 494 return false; |
| 487 } else { | 495 } else { |
| 488 return true; | 496 return true; |
| 489 } | 497 } |
| 490 } | 498 } |
| 491 | 499 |
| 492 void NativeDisplayDelegateX11::DestroyUnusedCrtcs() { | 500 void NativeDisplayDelegateX11::DestroyUnusedCrtcs() { |
| 493 CHECK(screen_) << "Server not grabbed"; | 501 // Server not grabbed |
| 502 CHECK(screen_); |
| 494 | 503 |
| 495 for (int i = 0; i < screen_->ncrtc; ++i) { | 504 for (int i = 0; i < screen_->ncrtc; ++i) { |
| 496 bool in_use = false; | 505 bool in_use = false; |
| 497 for (ScopedVector<DisplaySnapshot>::const_iterator it = | 506 for (ScopedVector<DisplaySnapshot>::const_iterator it = |
| 498 cached_outputs_.begin(); | 507 cached_outputs_.begin(); |
| 499 it != cached_outputs_.end(); | 508 it != cached_outputs_.end(); |
| 500 ++it) { | 509 ++it) { |
| 501 DisplaySnapshotX11* x11_output = static_cast<DisplaySnapshotX11*>(*it); | 510 DisplaySnapshotX11* x11_output = static_cast<DisplaySnapshotX11*>(*it); |
| 502 if (screen_->crtcs[i] == x11_output->crtc()) { | 511 if (screen_->crtcs[i] == x11_output->crtc()) { |
| 503 in_use = true; | 512 in_use = true; |
| 504 break; | 513 break; |
| 505 } | 514 } |
| 506 } | 515 } |
| 507 | 516 |
| 508 if (!in_use) | 517 if (!in_use) |
| 509 ConfigureCrtc(screen_->crtcs[i], None, None, 0, 0); | 518 ConfigureCrtc(screen_->crtcs[i], None, None, 0, 0); |
| 510 } | 519 } |
| 511 } | 520 } |
| 512 | 521 |
| 513 void NativeDisplayDelegateX11::UpdateCrtcsForNewFramebuffer( | 522 void NativeDisplayDelegateX11::UpdateCrtcsForNewFramebuffer( |
| 514 const gfx::Size& min_screen_size) { | 523 const gfx::Size& min_screen_size) { |
| 515 CHECK(screen_) << "Server not grabbed"; | 524 // Server not grabbed |
| 525 CHECK(screen_); |
| 516 // Setting the screen size will fail if any CRTC doesn't fit afterwards. | 526 // Setting the screen size will fail if any CRTC doesn't fit afterwards. |
| 517 // At the same time, turning CRTCs off and back on uses up a lot of time. | 527 // At the same time, turning CRTCs off and back on uses up a lot of time. |
| 518 // This function tries to be smart to avoid too many off/on cycles: | 528 // This function tries to be smart to avoid too many off/on cycles: |
| 519 // - We set the new modes on CRTCs, if they fit in both the old and new | 529 // - We set the new modes on CRTCs, if they fit in both the old and new |
| 520 // FBs, and park them at (0,0) | 530 // FBs, and park them at (0,0) |
| 521 // - We disable the CRTCs we will need but don't fit in the old FB. Those | 531 // - We disable the CRTCs we will need but don't fit in the old FB. Those |
| 522 // will be reenabled after the resize. | 532 // will be reenabled after the resize. |
| 523 // We don't worry about the cached state of the outputs here since we are | 533 // We don't worry about the cached state of the outputs here since we are |
| 524 // not interested in the state we are setting - we just try to get the CRTCs | 534 // not interested in the state we are setting - we just try to get the CRTCs |
| 525 // out of the way so we can rebuild the frame buffer. | 535 // out of the way so we can rebuild the frame buffer. |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 655 XSetForeground(display_, gc, color.pixel); | 665 XSetForeground(display_, gc, color.pixel); |
| 656 XSetFillStyle(display_, gc, FillSolid); | 666 XSetFillStyle(display_, gc, FillSolid); |
| 657 int width = DisplayWidth(display_, DefaultScreen(display_)); | 667 int width = DisplayWidth(display_, DefaultScreen(display_)); |
| 658 int height = DisplayHeight(display_, DefaultScreen(display_)); | 668 int height = DisplayHeight(display_, DefaultScreen(display_)); |
| 659 XFillRectangle(display_, window_, gc, 0, 0, width, height); | 669 XFillRectangle(display_, window_, gc, 0, 0, width, height); |
| 660 XFreeGC(display_, gc); | 670 XFreeGC(display_, gc); |
| 661 XFreeColors(display_, colormap, &color.pixel, 1, 0); | 671 XFreeColors(display_, colormap, &color.pixel, 1, 0); |
| 662 } | 672 } |
| 663 | 673 |
| 664 } // namespace ui | 674 } // namespace ui |
| OLD | NEW |