| 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/chromeos/x11/native_display_delegate_x11.h" | 5 #include "ui/display/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/Xrandr.h> | 10 #include <X11/extensions/Xrandr.h> |
| 11 #include <X11/extensions/XInput2.h> | 11 #include <X11/extensions/XInput2.h> |
| 12 | 12 |
| 13 #include <utility> | 13 #include <utility> |
| 14 | 14 |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
| 17 #include "base/message_loop/message_pump_x11.h" | 17 #include "base/message_loop/message_pump_x11.h" |
| 18 #include "base/stl_util.h" |
| 18 #include "base/x11/edid_parser_x11.h" | 19 #include "base/x11/edid_parser_x11.h" |
| 19 #include "base/x11/x11_error_tracker.h" | 20 #include "base/x11/x11_error_tracker.h" |
| 20 #include "ui/display/chromeos/native_display_observer.h" | 21 #include "ui/display/chromeos/native_display_observer.h" |
| 22 #include "ui/display/chromeos/x11/display_mode_x11.h" |
| 23 #include "ui/display/chromeos/x11/display_snapshot_x11.h" |
| 21 #include "ui/display/chromeos/x11/display_util.h" | 24 #include "ui/display/chromeos/x11/display_util.h" |
| 22 #include "ui/display/chromeos/x11/native_display_event_dispatcher_x11.h" | 25 #include "ui/display/chromeos/x11/native_display_event_dispatcher_x11.h" |
| 23 | 26 |
| 24 namespace ui { | 27 namespace ui { |
| 25 | 28 |
| 26 namespace { | 29 namespace { |
| 27 | 30 |
| 28 // DPI measurements. | 31 // DPI measurements. |
| 29 const float kMmInInch = 25.4; | 32 const float kMmInInch = 25.4; |
| 30 const float kDpi96 = 96.0; | 33 const float kDpi96 = 96.0; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 48 : public NativeDisplayDelegateX11::HelperDelegate { | 51 : public NativeDisplayDelegateX11::HelperDelegate { |
| 49 public: | 52 public: |
| 50 HelperDelegateX11(NativeDisplayDelegateX11* delegate) : delegate_(delegate) {} | 53 HelperDelegateX11(NativeDisplayDelegateX11* delegate) : delegate_(delegate) {} |
| 51 virtual ~HelperDelegateX11() {} | 54 virtual ~HelperDelegateX11() {} |
| 52 | 55 |
| 53 // NativeDisplayDelegateX11::HelperDelegate overrides: | 56 // NativeDisplayDelegateX11::HelperDelegate overrides: |
| 54 virtual void UpdateXRandRConfiguration(const base::NativeEvent& event) | 57 virtual void UpdateXRandRConfiguration(const base::NativeEvent& event) |
| 55 OVERRIDE { | 58 OVERRIDE { |
| 56 XRRUpdateConfiguration(event); | 59 XRRUpdateConfiguration(event); |
| 57 } | 60 } |
| 58 virtual const std::vector<OutputConfigurator::OutputSnapshot>& | 61 virtual const std::vector<DisplaySnapshot*>& GetCachedOutputs() const |
| 59 GetCachedOutputs() const OVERRIDE { | 62 OVERRIDE { |
| 60 return delegate_->cached_outputs_; | 63 return delegate_->cached_outputs_.get(); |
| 61 } | 64 } |
| 62 virtual void NotifyDisplayObservers() OVERRIDE { | 65 virtual void NotifyDisplayObservers() OVERRIDE { |
| 63 FOR_EACH_OBSERVER( | 66 FOR_EACH_OBSERVER( |
| 64 NativeDisplayObserver, delegate_->observers_, OnConfigurationChanged()); | 67 NativeDisplayObserver, delegate_->observers_, OnConfigurationChanged()); |
| 65 } | 68 } |
| 66 | 69 |
| 67 private: | 70 private: |
| 68 NativeDisplayDelegateX11* delegate_; | 71 NativeDisplayDelegateX11* delegate_; |
| 69 | 72 |
| 70 DISALLOW_COPY_AND_ASSIGN(HelperDelegateX11); | 73 DISALLOW_COPY_AND_ASSIGN(HelperDelegateX11); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 | 123 |
| 121 NativeDisplayDelegateX11::NativeDisplayDelegateX11() | 124 NativeDisplayDelegateX11::NativeDisplayDelegateX11() |
| 122 : display_(base::MessagePumpX11::GetDefaultXDisplay()), | 125 : display_(base::MessagePumpX11::GetDefaultXDisplay()), |
| 123 window_(DefaultRootWindow(display_)), | 126 window_(DefaultRootWindow(display_)), |
| 124 screen_(NULL) {} | 127 screen_(NULL) {} |
| 125 | 128 |
| 126 NativeDisplayDelegateX11::~NativeDisplayDelegateX11() { | 129 NativeDisplayDelegateX11::~NativeDisplayDelegateX11() { |
| 127 base::MessagePumpX11::Current()->RemoveDispatcherForRootWindow( | 130 base::MessagePumpX11::Current()->RemoveDispatcherForRootWindow( |
| 128 message_pump_dispatcher_.get()); | 131 message_pump_dispatcher_.get()); |
| 129 base::MessagePumpX11::Current()->RemoveObserver(message_pump_observer_.get()); | 132 base::MessagePumpX11::Current()->RemoveObserver(message_pump_observer_.get()); |
| 133 |
| 134 STLDeleteContainerPairSecondPointers(modes_.begin(), modes_.end()); |
| 130 } | 135 } |
| 131 | 136 |
| 132 void NativeDisplayDelegateX11::Initialize() { | 137 void NativeDisplayDelegateX11::Initialize() { |
| 133 int error_base_ignored = 0; | 138 int error_base_ignored = 0; |
| 134 int xrandr_event_base = 0; | 139 int xrandr_event_base = 0; |
| 135 XRRQueryExtension(display_, &xrandr_event_base, &error_base_ignored); | 140 XRRQueryExtension(display_, &xrandr_event_base, &error_base_ignored); |
| 136 | 141 |
| 137 helper_delegate_.reset(new HelperDelegateX11(this)); | 142 helper_delegate_.reset(new HelperDelegateX11(this)); |
| 138 message_pump_dispatcher_.reset(new NativeDisplayEventDispatcherX11( | 143 message_pump_dispatcher_.reset(new NativeDisplayEventDispatcherX11( |
| 139 helper_delegate_.get(), xrandr_event_base)); | 144 helper_delegate_.get(), xrandr_event_base)); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 swa.background_pixel = color.pixel; | 185 swa.background_pixel = color.pixel; |
| 181 XChangeWindowAttributes(display_, window_, CWBackPixel, &swa); | 186 XChangeWindowAttributes(display_, window_, CWBackPixel, &swa); |
| 182 XFreeColors(display_, colormap, &color.pixel, 1, 0); | 187 XFreeColors(display_, colormap, &color.pixel, 1, 0); |
| 183 } | 188 } |
| 184 | 189 |
| 185 void NativeDisplayDelegateX11::ForceDPMSOn() { | 190 void NativeDisplayDelegateX11::ForceDPMSOn() { |
| 186 CHECK(DPMSEnable(display_)); | 191 CHECK(DPMSEnable(display_)); |
| 187 CHECK(DPMSForceLevel(display_, DPMSModeOn)); | 192 CHECK(DPMSForceLevel(display_, DPMSModeOn)); |
| 188 } | 193 } |
| 189 | 194 |
| 190 std::vector<OutputConfigurator::OutputSnapshot> | 195 std::vector<DisplaySnapshot*> NativeDisplayDelegateX11::GetOutputs() { |
| 191 NativeDisplayDelegateX11::GetOutputs() { | |
| 192 CHECK(screen_) << "Server not grabbed"; | 196 CHECK(screen_) << "Server not grabbed"; |
| 193 | 197 |
| 194 cached_outputs_.clear(); | 198 cached_outputs_.clear(); |
| 195 RRCrtc last_used_crtc = None; | 199 RRCrtc last_used_crtc = None; |
| 196 | 200 |
| 201 InitModes(); |
| 197 for (int i = 0; i < screen_->noutput && cached_outputs_.size() < 2; ++i) { | 202 for (int i = 0; i < screen_->noutput && cached_outputs_.size() < 2; ++i) { |
| 198 RROutput output_id = screen_->outputs[i]; | 203 RROutput output_id = screen_->outputs[i]; |
| 199 XRROutputInfo* output_info = XRRGetOutputInfo(display_, screen_, output_id); | 204 XRROutputInfo* output_info = XRRGetOutputInfo(display_, screen_, output_id); |
| 200 if (output_info->connection == RR_Connected) { | 205 if (output_info->connection == RR_Connected) { |
| 201 OutputConfigurator::OutputSnapshot output = | 206 DisplaySnapshotX11* output = |
| 202 InitOutputSnapshot(output_id, output_info, &last_used_crtc, i); | 207 InitDisplaySnapshot(output_id, output_info, &last_used_crtc, i); |
| 203 VLOG(2) << "Found display " << cached_outputs_.size() << ":" | |
| 204 << " output=" << output.output << " crtc=" << output.crtc | |
| 205 << " current_mode=" << output.current_mode; | |
| 206 cached_outputs_.push_back(output); | 208 cached_outputs_.push_back(output); |
| 207 } | 209 } |
| 208 XRRFreeOutputInfo(output_info); | 210 XRRFreeOutputInfo(output_info); |
| 209 } | 211 } |
| 210 | 212 |
| 211 return cached_outputs_; | 213 return cached_outputs_.get(); |
| 212 } | 214 } |
| 213 | 215 |
| 214 void NativeDisplayDelegateX11::AddMode( | 216 void NativeDisplayDelegateX11::AddMode(const DisplaySnapshot& output, |
| 215 const OutputConfigurator::OutputSnapshot& output, | 217 const DisplayMode* mode) { |
| 216 RRMode mode) { | |
| 217 CHECK(screen_) << "Server not grabbed"; | 218 CHECK(screen_) << "Server not grabbed"; |
| 218 VLOG(1) << "AddOutputMode: output=" << output.output << " mode=" << mode; | 219 CHECK(mode) << "Must add valid mode"; |
| 219 XRRAddOutputMode(display_, output.output, mode); | 220 |
| 221 const DisplaySnapshotX11& x11_output = |
| 222 static_cast<const DisplaySnapshotX11&>(output); |
| 223 RRMode mode_id = static_cast<const DisplayModeX11*>(mode)->mode_id(); |
| 224 |
| 225 VLOG(1) << "AddOutputMode: output=" << x11_output.output() |
| 226 << " mode=" << mode_id; |
| 227 XRRAddOutputMode(display_, x11_output.output(), mode_id); |
| 220 } | 228 } |
| 221 | 229 |
| 222 bool NativeDisplayDelegateX11::Configure( | 230 bool NativeDisplayDelegateX11::Configure(const DisplaySnapshot& output, |
| 223 const OutputConfigurator::OutputSnapshot& output, | 231 const DisplayMode* mode, |
| 224 RRMode mode, | 232 const gfx::Point& origin) { |
| 225 int x, | 233 const DisplaySnapshotX11& x11_output = |
| 226 int y) { | 234 static_cast<const DisplaySnapshotX11&>(output); |
| 227 return ConfigureCrtc(output.crtc, mode, output.output, x, y); | 235 RRMode mode_id = None; |
| 236 if (mode) |
| 237 mode_id = static_cast<const DisplayModeX11*>(mode)->mode_id(); |
| 238 |
| 239 return ConfigureCrtc( |
| 240 x11_output.crtc(), mode_id, x11_output.output(), origin.x(), origin.y()); |
| 228 } | 241 } |
| 229 | 242 |
| 230 bool NativeDisplayDelegateX11::ConfigureCrtc(RRCrtc crtc, | 243 bool NativeDisplayDelegateX11::ConfigureCrtc(RRCrtc crtc, |
| 231 RRMode mode, | 244 RRMode mode, |
| 232 RROutput output, | 245 RROutput output, |
| 233 int x, | 246 int x, |
| 234 int y) { | 247 int y) { |
| 235 CHECK(screen_) << "Server not grabbed"; | 248 CHECK(screen_) << "Server not grabbed"; |
| 236 VLOG(1) << "ConfigureCrtc: crtc=" << crtc << " mode=" << mode | 249 VLOG(1) << "ConfigureCrtc: crtc=" << crtc << " mode=" << mode |
| 237 << " output=" << output << " x=" << x << " y=" << y; | 250 << " output=" << output << " x=" << x << " y=" << y; |
| 238 // Xrandr.h is full of lies. XRRSetCrtcConfig() is defined as returning a | 251 // Xrandr.h is full of lies. XRRSetCrtcConfig() is defined as returning a |
| 239 // Status, which is typically 0 for failure and 1 for success. In | 252 // Status, which is typically 0 for failure and 1 for success. In |
| 240 // actuality it returns a RRCONFIGSTATUS, which uses 0 for success. | 253 // actuality it returns a RRCONFIGSTATUS, which uses 0 for success. |
| 241 return XRRSetCrtcConfig(display_, | 254 if (XRRSetCrtcConfig(display_, |
| 242 screen_, | 255 screen_, |
| 243 crtc, | 256 crtc, |
| 244 CurrentTime, | 257 CurrentTime, |
| 245 x, | 258 x, |
| 246 y, | 259 y, |
| 247 mode, | 260 mode, |
| 248 RR_Rotate_0, | 261 RR_Rotate_0, |
| 249 (output && mode) ? &output : NULL, | 262 (output && mode) ? &output : NULL, |
| 250 (output && mode) ? 1 : 0) == RRSetConfigSuccess; | 263 (output && mode) ? 1 : 0) != RRSetConfigSuccess) { |
| 264 LOG(WARNING) << "Unable to configure CRTC " << crtc << ":" |
| 265 << " mode=" << mode << " output=" << output << " x=" << x |
| 266 << " y=" << y; |
| 267 return false; |
| 268 } |
| 269 |
| 270 return true; |
| 251 } | 271 } |
| 252 | 272 |
| 253 void NativeDisplayDelegateX11::CreateFrameBuffer( | 273 void NativeDisplayDelegateX11::CreateFrameBuffer(const gfx::Size& size) { |
| 254 int width, | |
| 255 int height, | |
| 256 const std::vector<OutputConfigurator::OutputSnapshot>& outputs) { | |
| 257 CHECK(screen_) << "Server not grabbed"; | 274 CHECK(screen_) << "Server not grabbed"; |
| 258 int current_width = DisplayWidth(display_, DefaultScreen(display_)); | 275 int current_width = DisplayWidth(display_, DefaultScreen(display_)); |
| 259 int current_height = DisplayHeight(display_, DefaultScreen(display_)); | 276 int current_height = DisplayHeight(display_, DefaultScreen(display_)); |
| 260 VLOG(1) << "CreateFrameBuffer: new=" << width << "x" << height | 277 VLOG(1) << "CreateFrameBuffer: new=" << size.width() << "x" << size.height() |
| 261 << " current=" << current_width << "x" << current_height; | 278 << " current=" << current_width << "x" << current_height; |
| 262 if (width == current_width && height == current_height) | 279 if (size.width() == current_width && size.height() == current_height) |
| 263 return; | 280 return; |
| 264 | 281 |
| 265 DestroyUnusedCrtcs(outputs); | 282 DestroyUnusedCrtcs(); |
| 266 int mm_width = width * kPixelsToMmScale; | 283 int mm_width = size.width() * kPixelsToMmScale; |
| 267 int mm_height = height * kPixelsToMmScale; | 284 int mm_height = size.height() * kPixelsToMmScale; |
| 268 XRRSetScreenSize(display_, window_, width, height, mm_width, mm_height); | 285 XRRSetScreenSize( |
| 286 display_, window_, size.width(), size.height(), mm_width, mm_height); |
| 269 } | 287 } |
| 270 | 288 |
| 271 bool NativeDisplayDelegateX11::InitModeInfo( | 289 void NativeDisplayDelegateX11::InitModes() { |
| 272 RRMode mode, | |
| 273 OutputConfigurator::ModeInfo* mode_info) { | |
| 274 DCHECK(mode_info); | |
| 275 CHECK(screen_) << "Server not grabbed"; | 290 CHECK(screen_) << "Server not grabbed"; |
| 276 // TODO: Determine if we need to organize modes in a way which provides | 291 |
| 277 // better than O(n) lookup time. In many call sites, for example, the | 292 STLDeleteContainerPairSecondPointers(modes_.begin(), modes_.end()); |
| 278 // "next" mode is typically what we are looking for so using this | 293 modes_.clear(); |
| 279 // helper might be too expensive. | 294 |
| 280 for (int i = 0; i < screen_->nmode; ++i) { | 295 for (int i = 0; i < screen_->nmode; ++i) { |
| 281 if (mode == screen_->modes[i].id) { | 296 const XRRModeInfo& info = screen_->modes[i]; |
| 282 const XRRModeInfo& info = screen_->modes[i]; | 297 float refresh_rate = 0.0f; |
| 283 mode_info->width = info.width; | 298 if (info.hTotal && info.vTotal) { |
| 284 mode_info->height = info.height; | 299 refresh_rate = |
| 285 mode_info->interlaced = info.modeFlags & RR_Interlace; | 300 static_cast<float>(info.dotClock) / |
| 286 if (info.hTotal && info.vTotal) { | 301 (static_cast<float>(info.hTotal) * static_cast<float>(info.vTotal)); |
| 287 mode_info->refresh_rate = | |
| 288 static_cast<float>(info.dotClock) / | |
| 289 (static_cast<float>(info.hTotal) * static_cast<float>(info.vTotal)); | |
| 290 } else { | |
| 291 mode_info->refresh_rate = 0.0f; | |
| 292 } | |
| 293 return true; | |
| 294 } | 302 } |
| 303 |
| 304 modes_.insert( |
| 305 std::make_pair(info.id, |
| 306 new DisplayModeX11(gfx::Size(info.width, info.height), |
| 307 info.modeFlags & RR_Interlace, |
| 308 refresh_rate, |
| 309 info.id))); |
| 295 } | 310 } |
| 296 return false; | |
| 297 } | 311 } |
| 298 | 312 |
| 299 OutputConfigurator::OutputSnapshot NativeDisplayDelegateX11::InitOutputSnapshot( | 313 DisplaySnapshotX11* NativeDisplayDelegateX11::InitDisplaySnapshot( |
| 300 RROutput id, | 314 RROutput id, |
| 301 XRROutputInfo* info, | 315 XRROutputInfo* info, |
| 302 RRCrtc* last_used_crtc, | 316 RRCrtc* last_used_crtc, |
| 303 int index) { | 317 int index) { |
| 304 OutputConfigurator::OutputSnapshot output; | 318 int64_t display_id = 0; |
| 305 output.output = id; | 319 bool has_display_id = base::GetDisplayId(id, index, &display_id); |
| 306 output.width_mm = info->mm_width; | |
| 307 output.height_mm = info->mm_height; | |
| 308 output.has_display_id = base::GetDisplayId(id, index, &output.display_id); | |
| 309 output.index = index; | |
| 310 output.type = GetOutputTypeFromName(info->name); | |
| 311 | 320 |
| 312 if (output.type == OUTPUT_TYPE_UNKNOWN) | 321 OutputType type = GetOutputTypeFromName(info->name); |
| 322 if (type == OUTPUT_TYPE_UNKNOWN) |
| 313 LOG(ERROR) << "Unknown link type: " << info->name; | 323 LOG(ERROR) << "Unknown link type: " << info->name; |
| 314 | 324 |
| 315 // Use the index as a valid display ID even if the internal | 325 // Use the index as a valid display ID even if the internal |
| 316 // display doesn't have valid EDID because the index | 326 // display doesn't have valid EDID because the index |
| 317 // will never change. | 327 // will never change. |
| 318 if (!output.has_display_id && output.type == OUTPUT_TYPE_INTERNAL) | 328 if (!has_display_id) { |
| 319 output.has_display_id = true; | 329 if (type == OUTPUT_TYPE_INTERNAL) |
| 330 has_display_id = true; |
| 320 | 331 |
| 332 // Fallback to output index. |
| 333 display_id = index; |
| 334 } |
| 335 |
| 336 RRMode native_mode_id = GetOutputNativeMode(info); |
| 337 RRMode current_mode_id = None; |
| 338 gfx::Point origin; |
| 321 if (info->crtc) { | 339 if (info->crtc) { |
| 322 XRRCrtcInfo* crtc_info = XRRGetCrtcInfo(display_, screen_, info->crtc); | 340 XRRCrtcInfo* crtc_info = XRRGetCrtcInfo(display_, screen_, info->crtc); |
| 323 output.current_mode = crtc_info->mode; | 341 current_mode_id = crtc_info->mode; |
| 324 output.x = crtc_info->x; | 342 origin.SetPoint(crtc_info->x, crtc_info->y); |
| 325 output.y = crtc_info->y; | |
| 326 XRRFreeCrtcInfo(crtc_info); | 343 XRRFreeCrtcInfo(crtc_info); |
| 327 } | 344 } |
| 328 | 345 |
| 346 RRCrtc crtc = None; |
| 329 // Assign a CRTC that isn't already in use. | 347 // Assign a CRTC that isn't already in use. |
| 330 for (int i = 0; i < info->ncrtc; ++i) { | 348 for (int i = 0; i < info->ncrtc; ++i) { |
| 331 if (info->crtcs[i] != *last_used_crtc) { | 349 if (info->crtcs[i] != *last_used_crtc) { |
| 332 output.crtc = info->crtcs[i]; | 350 crtc = info->crtcs[i]; |
| 333 *last_used_crtc = output.crtc; | 351 *last_used_crtc = crtc; |
| 334 break; | 352 break; |
| 335 } | 353 } |
| 336 } | 354 } |
| 337 | 355 |
| 338 output.native_mode = GetOutputNativeMode(info); | 356 const DisplayMode* current_mode = NULL; |
| 339 output.is_aspect_preserving_scaling = IsOutputAspectPreservingScaling(id); | 357 const DisplayMode* native_mode = NULL; |
| 340 output.touch_device_id = None; | 358 std::vector<const DisplayMode*> display_modes; |
| 341 | |
| 342 for (int i = 0; i < info->nmode; ++i) { | 359 for (int i = 0; i < info->nmode; ++i) { |
| 343 const RRMode mode = info->modes[i]; | 360 const RRMode mode = info->modes[i]; |
| 344 OutputConfigurator::ModeInfo mode_info; | 361 if (modes_.find(mode) != modes_.end()) { |
| 345 if (InitModeInfo(mode, &mode_info)) | 362 display_modes.push_back(modes_.at(mode)); |
| 346 output.mode_infos.insert(std::make_pair(mode, mode_info)); | 363 |
| 347 else | 364 if (mode == current_mode_id) |
| 365 current_mode = display_modes.back(); |
| 366 if (mode == native_mode_id) |
| 367 native_mode = display_modes.back(); |
| 368 } else { |
| 348 LOG(WARNING) << "Unable to find XRRModeInfo for mode " << mode; | 369 LOG(WARNING) << "Unable to find XRRModeInfo for mode " << mode; |
| 370 } |
| 349 } | 371 } |
| 350 | 372 |
| 373 DisplaySnapshotX11* output = |
| 374 new DisplaySnapshotX11(display_id, |
| 375 has_display_id, |
| 376 origin, |
| 377 gfx::Size(info->mm_width, info->mm_height), |
| 378 type, |
| 379 IsOutputAspectPreservingScaling(id), |
| 380 display_modes, |
| 381 current_mode, |
| 382 native_mode, |
| 383 id, |
| 384 crtc, |
| 385 index); |
| 386 |
| 387 VLOG(2) << "Found display " << cached_outputs_.size() << ":" |
| 388 << " output=" << output << " crtc=" << crtc |
| 389 << " current_mode=" << current_mode_id; |
| 390 |
| 351 return output; | 391 return output; |
| 352 } | 392 } |
| 353 | 393 |
| 354 bool NativeDisplayDelegateX11::GetHDCPState( | 394 bool NativeDisplayDelegateX11::GetHDCPState(const DisplaySnapshot& output, |
| 355 const OutputConfigurator::OutputSnapshot& output, | 395 HDCPState* state) { |
| 356 HDCPState* state) { | |
| 357 unsigned char* values = NULL; | 396 unsigned char* values = NULL; |
| 358 int actual_format = 0; | 397 int actual_format = 0; |
| 359 unsigned long nitems = 0; | 398 unsigned long nitems = 0; |
| 360 unsigned long bytes_after = 0; | 399 unsigned long bytes_after = 0; |
| 361 Atom actual_type = None; | 400 Atom actual_type = None; |
| 362 int success = 0; | 401 int success = 0; |
| 402 RROutput output_id = static_cast<const DisplaySnapshotX11&>(output).output(); |
| 363 // TODO(kcwu): Use X11AtomCache to save round trip time of XInternAtom. | 403 // TODO(kcwu): Use X11AtomCache to save round trip time of XInternAtom. |
| 364 Atom prop = XInternAtom(display_, kContentProtectionAtomName, False); | 404 Atom prop = XInternAtom(display_, kContentProtectionAtomName, False); |
| 365 | 405 |
| 366 bool ok = true; | 406 bool ok = true; |
| 367 // TODO(kcwu): Move this to x11_util (similar method calls in this file and | 407 // TODO(kcwu): Move this to x11_util (similar method calls in this file and |
| 368 // output_util.cc) | 408 // output_util.cc) |
| 369 success = XRRGetOutputProperty(display_, | 409 success = XRRGetOutputProperty(display_, |
| 370 output.output, | 410 output_id, |
| 371 prop, | 411 prop, |
| 372 0, | 412 0, |
| 373 100, | 413 100, |
| 374 False, | 414 False, |
| 375 False, | 415 False, |
| 376 AnyPropertyType, | 416 AnyPropertyType, |
| 377 &actual_type, | 417 &actual_type, |
| 378 &actual_format, | 418 &actual_format, |
| 379 &nitems, | 419 &nitems, |
| 380 &bytes_after, | 420 &bytes_after, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 403 LOG(ERROR) << "XRRGetOutputProperty failed"; | 443 LOG(ERROR) << "XRRGetOutputProperty failed"; |
| 404 ok = false; | 444 ok = false; |
| 405 } | 445 } |
| 406 if (values) | 446 if (values) |
| 407 XFree(values); | 447 XFree(values); |
| 408 | 448 |
| 409 VLOG(3) << "HDCP state: " << ok << "," << *state; | 449 VLOG(3) << "HDCP state: " << ok << "," << *state; |
| 410 return ok; | 450 return ok; |
| 411 } | 451 } |
| 412 | 452 |
| 413 bool NativeDisplayDelegateX11::SetHDCPState( | 453 bool NativeDisplayDelegateX11::SetHDCPState(const DisplaySnapshot& output, |
| 414 const OutputConfigurator::OutputSnapshot& output, | 454 HDCPState state) { |
| 415 HDCPState state) { | |
| 416 Atom name = XInternAtom(display_, kContentProtectionAtomName, False); | 455 Atom name = XInternAtom(display_, kContentProtectionAtomName, False); |
| 417 Atom value = None; | 456 Atom value = None; |
| 418 switch (state) { | 457 switch (state) { |
| 419 case HDCP_STATE_UNDESIRED: | 458 case HDCP_STATE_UNDESIRED: |
| 420 value = XInternAtom(display_, kProtectionUndesiredAtomName, False); | 459 value = XInternAtom(display_, kProtectionUndesiredAtomName, False); |
| 421 break; | 460 break; |
| 422 case HDCP_STATE_DESIRED: | 461 case HDCP_STATE_DESIRED: |
| 423 value = XInternAtom(display_, kProtectionDesiredAtomName, False); | 462 value = XInternAtom(display_, kProtectionDesiredAtomName, False); |
| 424 break; | 463 break; |
| 425 default: | 464 default: |
| 426 NOTREACHED() << "Invalid HDCP state: " << state; | 465 NOTREACHED() << "Invalid HDCP state: " << state; |
| 427 return false; | 466 return false; |
| 428 } | 467 } |
| 429 base::X11ErrorTracker err_tracker; | 468 base::X11ErrorTracker err_tracker; |
| 430 unsigned char* data = reinterpret_cast<unsigned char*>(&value); | 469 unsigned char* data = reinterpret_cast<unsigned char*>(&value); |
| 470 RROutput output_id = static_cast<const DisplaySnapshotX11&>(output).output(); |
| 431 XRRChangeOutputProperty( | 471 XRRChangeOutputProperty( |
| 432 display_, output.output, name, XA_ATOM, 32, PropModeReplace, data, 1); | 472 display_, output_id, name, XA_ATOM, 32, PropModeReplace, data, 1); |
| 433 if (err_tracker.FoundNewError()) { | 473 if (err_tracker.FoundNewError()) { |
| 434 LOG(ERROR) << "XRRChangeOutputProperty failed"; | 474 LOG(ERROR) << "XRRChangeOutputProperty failed"; |
| 435 return false; | 475 return false; |
| 436 } else { | 476 } else { |
| 437 return true; | 477 return true; |
| 438 } | 478 } |
| 439 } | 479 } |
| 440 | 480 |
| 441 void NativeDisplayDelegateX11::DestroyUnusedCrtcs( | 481 void NativeDisplayDelegateX11::DestroyUnusedCrtcs() { |
| 442 const std::vector<OutputConfigurator::OutputSnapshot>& outputs) { | |
| 443 CHECK(screen_) << "Server not grabbed"; | 482 CHECK(screen_) << "Server not grabbed"; |
| 444 // Setting the screen size will fail if any CRTC doesn't fit afterwards. | 483 // Setting the screen size will fail if any CRTC doesn't fit afterwards. |
| 445 // At the same time, turning CRTCs off and back on uses up a lot of time. | 484 // At the same time, turning CRTCs off and back on uses up a lot of time. |
| 446 // This function tries to be smart to avoid too many off/on cycles: | 485 // This function tries to be smart to avoid too many off/on cycles: |
| 447 // - We disable all the CRTCs we won't need after the FB resize. | 486 // - We disable all the CRTCs we won't need after the FB resize. |
| 448 // - We set the new modes on CRTCs, if they fit in both the old and new | 487 // - We set the new modes on CRTCs, if they fit in both the old and new |
| 449 // FBs, and park them at (0,0) | 488 // FBs, and park them at (0,0) |
| 450 // - We disable the CRTCs we will need but don't fit in the old FB. Those | 489 // - We disable the CRTCs we will need but don't fit in the old FB. Those |
| 451 // will be reenabled after the resize. | 490 // will be reenabled after the resize. |
| 452 // We don't worry about the cached state of the outputs here since we are | 491 // We don't worry about the cached state of the outputs here since we are |
| 453 // not interested in the state we are setting - we just try to get the CRTCs | 492 // not interested in the state we are setting - we just try to get the CRTCs |
| 454 // out of the way so we can rebuild the frame buffer. | 493 // out of the way so we can rebuild the frame buffer. |
| 455 for (int i = 0; i < screen_->ncrtc; ++i) { | 494 for (int i = 0; i < screen_->ncrtc; ++i) { |
| 456 // Default config is to disable the crtcs. | 495 // Default config is to disable the crtcs. |
| 457 RRCrtc crtc = screen_->crtcs[i]; | 496 RRCrtc crtc = screen_->crtcs[i]; |
| 458 RRMode mode = None; | 497 RRMode mode = None; |
| 459 RROutput output = None; | 498 RROutput output = None; |
| 460 const OutputConfigurator::ModeInfo* mode_info = NULL; | 499 const DisplayMode* mode_info = NULL; |
| 461 for (std::vector<OutputConfigurator::OutputSnapshot>::const_iterator it = | 500 for (ScopedVector<DisplaySnapshot>::const_iterator it = |
| 462 outputs.begin(); | 501 cached_outputs_.begin(); |
| 463 it != outputs.end(); | 502 it != cached_outputs_.end(); |
| 464 ++it) { | 503 ++it) { |
| 465 if (crtc == it->crtc) { | 504 DisplaySnapshotX11* x11_output = static_cast<DisplaySnapshotX11*>(*it); |
| 466 mode = it->current_mode; | 505 if (crtc == x11_output->crtc()) { |
| 467 output = it->output; | 506 mode_info = x11_output->current_mode(); |
| 468 if (mode != None) | 507 output = x11_output->output(); |
| 469 mode_info = OutputConfigurator::GetModeInfo(*it, mode); | |
| 470 break; | 508 break; |
| 471 } | 509 } |
| 472 } | 510 } |
| 473 | 511 |
| 474 if (mode_info) { | 512 if (mode_info) { |
| 513 mode = static_cast<const DisplayModeX11*>(mode_info)->mode_id(); |
| 475 // In case our CRTC doesn't fit in our current framebuffer, disable it. | 514 // In case our CRTC doesn't fit in our current framebuffer, disable it. |
| 476 // It'll get reenabled after we resize the framebuffer. | 515 // It'll get reenabled after we resize the framebuffer. |
| 477 int current_width = DisplayWidth(display_, DefaultScreen(display_)); | 516 int current_width = DisplayWidth(display_, DefaultScreen(display_)); |
| 478 int current_height = DisplayHeight(display_, DefaultScreen(display_)); | 517 int current_height = DisplayHeight(display_, DefaultScreen(display_)); |
| 479 if (mode_info->width > current_width || | 518 if (mode_info->size().width() > current_width || |
| 480 mode_info->height > current_height) { | 519 mode_info->size().height() > current_height) { |
| 481 mode = None; | 520 mode = None; |
| 482 output = None; | 521 output = None; |
| 483 mode_info = NULL; | 522 mode_info = NULL; |
| 484 } | 523 } |
| 485 } | 524 } |
| 486 | 525 |
| 487 ConfigureCrtc(crtc, mode, output, 0, 0); | 526 ConfigureCrtc(crtc, mode, output, 0, 0); |
| 488 } | 527 } |
| 489 } | 528 } |
| 490 | 529 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 | 578 |
| 540 void NativeDisplayDelegateX11::AddObserver(NativeDisplayObserver* observer) { | 579 void NativeDisplayDelegateX11::AddObserver(NativeDisplayObserver* observer) { |
| 541 observers_.AddObserver(observer); | 580 observers_.AddObserver(observer); |
| 542 } | 581 } |
| 543 | 582 |
| 544 void NativeDisplayDelegateX11::RemoveObserver(NativeDisplayObserver* observer) { | 583 void NativeDisplayDelegateX11::RemoveObserver(NativeDisplayObserver* observer) { |
| 545 observers_.RemoveObserver(observer); | 584 observers_.RemoveObserver(observer); |
| 546 } | 585 } |
| 547 | 586 |
| 548 } // namespace ui | 587 } // namespace ui |
| OLD | NEW |