EME test page application.
[chromium-blink-merge.git] / ui / display / chromeos / x11 / native_display_delegate_x11.cc
blobfb965d996459181babab8e054b7145ef1cd22a27
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
3 // found in the LICENSE file.
5 #include "ui/display/chromeos/x11/native_display_delegate_x11.h"
7 #include <X11/Xatom.h>
8 #include <X11/Xlib.h>
9 #include <X11/extensions/dpms.h>
10 #include <X11/extensions/Xrandr.h>
11 #include <X11/extensions/XInput2.h>
13 #include <utility>
15 #include "base/logging.h"
16 #include "base/stl_util.h"
17 #include "ui/display/chromeos/x11/display_mode_x11.h"
18 #include "ui/display/chromeos/x11/display_snapshot_x11.h"
19 #include "ui/display/chromeos/x11/display_util_x11.h"
20 #include "ui/display/chromeos/x11/native_display_event_dispatcher_x11.h"
21 #include "ui/display/types/chromeos/native_display_observer.h"
22 #include "ui/display/util/x11/edid_parser_x11.h"
23 #include "ui/events/platform/platform_event_observer.h"
24 #include "ui/events/platform/platform_event_source.h"
25 #include "ui/gfx/x/x11_error_tracker.h"
26 #include "ui/gfx/x/x11_types.h"
28 namespace ui {
30 namespace {
32 // DPI measurements.
33 const float kMmInInch = 25.4;
34 const float kDpi96 = 96.0;
35 const float kPixelsToMmScale = kMmInInch / kDpi96;
37 const char kContentProtectionAtomName[] = "Content Protection";
38 const char kProtectionUndesiredAtomName[] = "Undesired";
39 const char kProtectionDesiredAtomName[] = "Desired";
40 const char kProtectionEnabledAtomName[] = "Enabled";
42 RRMode GetOutputNativeMode(const XRROutputInfo* output_info) {
43 return output_info->nmode > 0 ? output_info->modes[0] : None;
46 XRRCrtcGamma* ResampleGammaRamp(XRRCrtcGamma* gamma_ramp, int gamma_ramp_size) {
47 if (gamma_ramp->size == gamma_ramp_size)
48 return gamma_ramp;
50 #define RESAMPLE(array, i, r) \
51 array[i] + (array[i + 1] - array[i]) * r / gamma_ramp_size
53 XRRCrtcGamma* resampled = XRRAllocGamma(gamma_ramp_size);
54 for (int i = 0; i < gamma_ramp_size; ++i) {
55 int base_index = gamma_ramp->size * i / gamma_ramp_size;
56 int remaining = gamma_ramp->size * i % gamma_ramp_size;
57 if (base_index < gamma_ramp->size - 1) {
58 resampled->red[i] = RESAMPLE(gamma_ramp->red, base_index, remaining);
59 resampled->green[i] = RESAMPLE(gamma_ramp->green, base_index, remaining);
60 resampled->blue[i] = RESAMPLE(gamma_ramp->blue, base_index, remaining);
61 } else {
62 resampled->red[i] = gamma_ramp->red[gamma_ramp->size - 1];
63 resampled->green[i] = gamma_ramp->green[gamma_ramp->size - 1];
64 resampled->blue[i] = gamma_ramp->blue[gamma_ramp->size - 1];
68 #undef RESAMPLE
69 XRRFreeGamma(gamma_ramp);
70 return resampled;
73 } // namespace
75 ////////////////////////////////////////////////////////////////////////////////
76 // NativeDisplayDelegateX11::HelperDelegateX11
78 class NativeDisplayDelegateX11::HelperDelegateX11
79 : public NativeDisplayDelegateX11::HelperDelegate {
80 public:
81 HelperDelegateX11(NativeDisplayDelegateX11* delegate) : delegate_(delegate) {}
82 virtual ~HelperDelegateX11() {}
84 // NativeDisplayDelegateX11::HelperDelegate overrides:
85 virtual void UpdateXRandRConfiguration(const base::NativeEvent& event)
86 OVERRIDE {
87 XRRUpdateConfiguration(event);
89 virtual const std::vector<DisplaySnapshot*>& GetCachedDisplays() const
90 OVERRIDE {
91 return delegate_->cached_outputs_.get();
93 virtual void NotifyDisplayObservers() OVERRIDE {
94 FOR_EACH_OBSERVER(
95 NativeDisplayObserver, delegate_->observers_, OnConfigurationChanged());
98 private:
99 NativeDisplayDelegateX11* delegate_;
101 DISALLOW_COPY_AND_ASSIGN(HelperDelegateX11);
104 ////////////////////////////////////////////////////////////////////////////////
105 // NativeDisplayDelegateX11::PlatformEventObserverX11
107 class NativeDisplayDelegateX11::PlatformEventObserverX11
108 : public PlatformEventObserver {
109 public:
110 PlatformEventObserverX11(HelperDelegate* delegate);
111 virtual ~PlatformEventObserverX11();
113 // PlatformEventObserverX11:
114 virtual void WillProcessEvent(const ui::PlatformEvent& event) OVERRIDE;
115 virtual void DidProcessEvent(const ui::PlatformEvent& event) OVERRIDE;
117 private:
118 HelperDelegate* delegate_; // Not owned.
120 DISALLOW_COPY_AND_ASSIGN(PlatformEventObserverX11);
123 NativeDisplayDelegateX11::PlatformEventObserverX11::PlatformEventObserverX11(
124 HelperDelegate* delegate)
125 : delegate_(delegate) {}
127 NativeDisplayDelegateX11::PlatformEventObserverX11::
128 ~PlatformEventObserverX11() {}
130 void NativeDisplayDelegateX11::PlatformEventObserverX11::WillProcessEvent(
131 const ui::PlatformEvent& event) {
132 // XI_HierarchyChanged events are special. There is no window associated with
133 // these events. So process them directly from here.
134 if (event->type == GenericEvent &&
135 event->xgeneric.evtype == XI_HierarchyChanged) {
136 VLOG(1) << "Received XI_HierarchyChanged event";
137 // Defer configuring outputs to not stall event processing.
138 // This also takes care of same event being received twice.
139 delegate_->NotifyDisplayObservers();
143 void NativeDisplayDelegateX11::PlatformEventObserverX11::DidProcessEvent(
144 const ui::PlatformEvent& event) {}
146 ////////////////////////////////////////////////////////////////////////////////
147 // NativeDisplayDelegateX11 implementation:
149 NativeDisplayDelegateX11::NativeDisplayDelegateX11()
150 : display_(gfx::GetXDisplay()),
151 window_(DefaultRootWindow(display_)),
152 screen_(NULL),
153 background_color_argb_(0) {}
155 NativeDisplayDelegateX11::~NativeDisplayDelegateX11() {
156 if (ui::PlatformEventSource::GetInstance()) {
157 ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(
158 platform_event_dispatcher_.get());
159 ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(
160 platform_event_observer_.get());
163 STLDeleteContainerPairSecondPointers(modes_.begin(), modes_.end());
166 void NativeDisplayDelegateX11::Initialize() {
167 int error_base_ignored = 0;
168 int xrandr_event_base = 0;
169 XRRQueryExtension(display_, &xrandr_event_base, &error_base_ignored);
171 helper_delegate_.reset(new HelperDelegateX11(this));
172 platform_event_dispatcher_.reset(new NativeDisplayEventDispatcherX11(
173 helper_delegate_.get(), xrandr_event_base));
174 platform_event_observer_.reset(
175 new PlatformEventObserverX11(helper_delegate_.get()));
177 if (ui::PlatformEventSource::GetInstance()) {
178 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(
179 platform_event_dispatcher_.get());
181 // We can't do this with a root window listener because XI_HierarchyChanged
182 // messages don't have a target window.
183 ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(
184 platform_event_observer_.get());
188 void NativeDisplayDelegateX11::GrabServer() {
189 CHECK(!screen_) << "Server already grabbed";
190 XGrabServer(display_);
191 screen_ = XRRGetScreenResources(display_, window_);
192 CHECK(screen_);
195 void NativeDisplayDelegateX11::UngrabServer() {
196 CHECK(screen_) << "Server not grabbed";
197 XRRFreeScreenResources(screen_);
198 screen_ = NULL;
199 XUngrabServer(display_);
200 // crbug.com/366125
201 XFlush(display_);
204 void NativeDisplayDelegateX11::SyncWithServer() { XSync(display_, 0); }
206 void NativeDisplayDelegateX11::SetBackgroundColor(uint32_t color_argb) {
207 background_color_argb_ = color_argb;
210 void NativeDisplayDelegateX11::ForceDPMSOn() {
211 CHECK(DPMSEnable(display_));
212 CHECK(DPMSForceLevel(display_, DPMSModeOn));
215 std::vector<DisplaySnapshot*> NativeDisplayDelegateX11::GetDisplays() {
216 CHECK(screen_) << "Server not grabbed";
218 cached_outputs_.clear();
219 RRCrtc last_used_crtc = None;
221 InitModes();
222 for (int i = 0; i < screen_->noutput && cached_outputs_.size() < 2; ++i) {
223 RROutput output_id = screen_->outputs[i];
224 XRROutputInfo* output_info = XRRGetOutputInfo(display_, screen_, output_id);
225 if (output_info->connection == RR_Connected) {
226 DisplaySnapshotX11* output =
227 InitDisplaySnapshot(output_id, output_info, &last_used_crtc, i);
228 cached_outputs_.push_back(output);
230 XRRFreeOutputInfo(output_info);
233 return cached_outputs_.get();
236 void NativeDisplayDelegateX11::AddMode(const DisplaySnapshot& output,
237 const DisplayMode* mode) {
238 CHECK(screen_) << "Server not grabbed";
239 CHECK(mode) << "Must add valid mode";
241 const DisplaySnapshotX11& x11_output =
242 static_cast<const DisplaySnapshotX11&>(output);
243 RRMode mode_id = static_cast<const DisplayModeX11*>(mode)->mode_id();
245 VLOG(1) << "AddDisplayMode: output=" << x11_output.output()
246 << " mode=" << mode_id;
247 XRRAddOutputMode(display_, x11_output.output(), mode_id);
250 bool NativeDisplayDelegateX11::Configure(const DisplaySnapshot& output,
251 const DisplayMode* mode,
252 const gfx::Point& origin) {
253 const DisplaySnapshotX11& x11_output =
254 static_cast<const DisplaySnapshotX11&>(output);
255 RRMode mode_id = None;
256 if (mode)
257 mode_id = static_cast<const DisplayModeX11*>(mode)->mode_id();
259 return ConfigureCrtc(
260 x11_output.crtc(), mode_id, x11_output.output(), origin.x(), origin.y());
263 bool NativeDisplayDelegateX11::ConfigureCrtc(RRCrtc crtc,
264 RRMode mode,
265 RROutput output,
266 int x,
267 int y) {
268 CHECK(screen_) << "Server not grabbed";
269 VLOG(1) << "ConfigureCrtc: crtc=" << crtc << " mode=" << mode
270 << " output=" << output << " x=" << x << " y=" << y;
271 // Xrandr.h is full of lies. XRRSetCrtcConfig() is defined as returning a
272 // Status, which is typically 0 for failure and 1 for success. In
273 // actuality it returns a RRCONFIGSTATUS, which uses 0 for success.
274 if (XRRSetCrtcConfig(display_,
275 screen_,
276 crtc,
277 CurrentTime,
280 mode,
281 RR_Rotate_0,
282 (output && mode) ? &output : NULL,
283 (output && mode) ? 1 : 0) != RRSetConfigSuccess) {
284 LOG(WARNING) << "Unable to configure CRTC " << crtc << ":"
285 << " mode=" << mode << " output=" << output << " x=" << x
286 << " y=" << y;
287 return false;
290 return true;
293 void NativeDisplayDelegateX11::CreateFrameBuffer(const gfx::Size& size) {
294 CHECK(screen_) << "Server not grabbed";
295 int current_width = DisplayWidth(display_, DefaultScreen(display_));
296 int current_height = DisplayHeight(display_, DefaultScreen(display_));
297 VLOG(1) << "CreateFrameBuffer: new=" << size.width() << "x" << size.height()
298 << " current=" << current_width << "x" << current_height;
300 DestroyUnusedCrtcs(size);
302 if (size.width() == current_width && size.height() == current_height)
303 return;
305 int mm_width = size.width() * kPixelsToMmScale;
306 int mm_height = size.height() * kPixelsToMmScale;
307 XRRSetScreenSize(
308 display_, window_, size.width(), size.height(), mm_width, mm_height);
309 // We don't wait for root window resize, therefore this end up with drawing
310 // in the old window size, which we care during the boot.
311 DrawBackground();
313 // Don't redraw the background upon framebuffer change again. This should
314 // happen only once after boot.
315 background_color_argb_ = 0;
318 void NativeDisplayDelegateX11::AddObserver(NativeDisplayObserver* observer) {
319 observers_.AddObserver(observer);
322 void NativeDisplayDelegateX11::RemoveObserver(NativeDisplayObserver* observer) {
323 observers_.RemoveObserver(observer);
326 void NativeDisplayDelegateX11::InitModes() {
327 CHECK(screen_) << "Server not grabbed";
329 STLDeleteContainerPairSecondPointers(modes_.begin(), modes_.end());
330 modes_.clear();
332 for (int i = 0; i < screen_->nmode; ++i) {
333 const XRRModeInfo& info = screen_->modes[i];
334 float refresh_rate = 0.0f;
335 if (info.hTotal && info.vTotal) {
336 refresh_rate =
337 static_cast<float>(info.dotClock) /
338 (static_cast<float>(info.hTotal) * static_cast<float>(info.vTotal));
341 modes_.insert(
342 std::make_pair(info.id,
343 new DisplayModeX11(gfx::Size(info.width, info.height),
344 info.modeFlags & RR_Interlace,
345 refresh_rate,
346 info.id)));
350 DisplaySnapshotX11* NativeDisplayDelegateX11::InitDisplaySnapshot(
351 RROutput id,
352 XRROutputInfo* info,
353 RRCrtc* last_used_crtc,
354 int index) {
355 int64_t display_id = 0;
356 bool has_display_id = GetDisplayId(
357 id, static_cast<uint8_t>(index), &display_id);
359 bool has_overscan = false;
360 GetOutputOverscanFlag(id, &has_overscan);
362 DisplayConnectionType type = GetDisplayConnectionTypeFromName(info->name);
363 if (type == DISPLAY_CONNECTION_TYPE_UNKNOWN)
364 LOG(ERROR) << "Unknown link type: " << info->name;
366 // Use the index as a valid display ID even if the internal
367 // display doesn't have valid EDID because the index
368 // will never change.
369 if (!has_display_id) {
370 if (type == DISPLAY_CONNECTION_TYPE_INTERNAL)
371 has_display_id = true;
373 // Fallback to output index.
374 display_id = index;
377 RRMode native_mode_id = GetOutputNativeMode(info);
378 RRMode current_mode_id = None;
379 gfx::Point origin;
380 if (info->crtc) {
381 XRRCrtcInfo* crtc_info = XRRGetCrtcInfo(display_, screen_, info->crtc);
382 current_mode_id = crtc_info->mode;
383 origin.SetPoint(crtc_info->x, crtc_info->y);
384 XRRFreeCrtcInfo(crtc_info);
387 RRCrtc crtc = None;
388 // Assign a CRTC that isn't already in use.
389 for (int i = 0; i < info->ncrtc; ++i) {
390 if (info->crtcs[i] != *last_used_crtc) {
391 crtc = info->crtcs[i];
392 *last_used_crtc = crtc;
393 break;
397 const DisplayMode* current_mode = NULL;
398 const DisplayMode* native_mode = NULL;
399 std::vector<const DisplayMode*> display_modes;
401 for (int i = 0; i < info->nmode; ++i) {
402 const RRMode mode = info->modes[i];
403 if (modes_.find(mode) != modes_.end()) {
404 display_modes.push_back(modes_.at(mode));
406 if (mode == current_mode_id)
407 current_mode = display_modes.back();
408 if (mode == native_mode_id)
409 native_mode = display_modes.back();
410 } else {
411 LOG(WARNING) << "Unable to find XRRModeInfo for mode " << mode;
415 DisplaySnapshotX11* output =
416 new DisplaySnapshotX11(display_id,
417 has_display_id,
418 origin,
419 gfx::Size(info->mm_width, info->mm_height),
420 type,
421 IsOutputAspectPreservingScaling(id),
422 has_overscan,
423 GetDisplayName(id),
424 display_modes,
425 current_mode,
426 native_mode,
428 crtc,
429 index);
431 VLOG(2) << "Found display " << cached_outputs_.size() << ":"
432 << " output=" << output << " crtc=" << crtc
433 << " current_mode=" << current_mode_id;
435 return output;
438 bool NativeDisplayDelegateX11::GetHDCPState(const DisplaySnapshot& output,
439 HDCPState* state) {
440 unsigned char* values = NULL;
441 int actual_format = 0;
442 unsigned long nitems = 0;
443 unsigned long bytes_after = 0;
444 Atom actual_type = None;
445 int success = 0;
446 RROutput output_id = static_cast<const DisplaySnapshotX11&>(output).output();
447 // TODO(kcwu): Use X11AtomCache to save round trip time of XInternAtom.
448 Atom prop = XInternAtom(display_, kContentProtectionAtomName, False);
450 bool ok = true;
451 // TODO(kcwu): Move this to x11_util (similar method calls in this file and
452 // output_util.cc)
453 success = XRRGetOutputProperty(display_,
454 output_id,
455 prop,
457 100,
458 False,
459 False,
460 AnyPropertyType,
461 &actual_type,
462 &actual_format,
463 &nitems,
464 &bytes_after,
465 &values);
466 if (actual_type == None) {
467 LOG(ERROR) << "Property '" << kContentProtectionAtomName
468 << "' does not exist";
469 ok = false;
470 } else if (success == Success && actual_type == XA_ATOM &&
471 actual_format == 32 && nitems == 1) {
472 Atom value = reinterpret_cast<Atom*>(values)[0];
473 if (value == XInternAtom(display_, kProtectionUndesiredAtomName, False)) {
474 *state = HDCP_STATE_UNDESIRED;
475 } else if (value ==
476 XInternAtom(display_, kProtectionDesiredAtomName, False)) {
477 *state = HDCP_STATE_DESIRED;
478 } else if (value ==
479 XInternAtom(display_, kProtectionEnabledAtomName, False)) {
480 *state = HDCP_STATE_ENABLED;
481 } else {
482 LOG(ERROR) << "Unknown " << kContentProtectionAtomName
483 << " value: " << value;
484 ok = false;
486 } else {
487 LOG(ERROR) << "XRRGetOutputProperty failed";
488 ok = false;
490 if (values)
491 XFree(values);
493 VLOG(3) << "HDCP state: " << ok << "," << *state;
494 return ok;
497 bool NativeDisplayDelegateX11::SetHDCPState(const DisplaySnapshot& output,
498 HDCPState state) {
499 Atom name = XInternAtom(display_, kContentProtectionAtomName, False);
500 Atom value = None;
501 switch (state) {
502 case HDCP_STATE_UNDESIRED:
503 value = XInternAtom(display_, kProtectionUndesiredAtomName, False);
504 break;
505 case HDCP_STATE_DESIRED:
506 value = XInternAtom(display_, kProtectionDesiredAtomName, False);
507 break;
508 default:
509 NOTREACHED() << "Invalid HDCP state: " << state;
510 return false;
512 gfx::X11ErrorTracker err_tracker;
513 unsigned char* data = reinterpret_cast<unsigned char*>(&value);
514 RROutput output_id = static_cast<const DisplaySnapshotX11&>(output).output();
515 XRRChangeOutputProperty(
516 display_, output_id, name, XA_ATOM, 32, PropModeReplace, data, 1);
517 if (err_tracker.FoundNewError()) {
518 LOG(ERROR) << "XRRChangeOutputProperty failed";
519 return false;
520 } else {
521 return true;
525 void NativeDisplayDelegateX11::DestroyUnusedCrtcs(const gfx::Size& new_size) {
526 CHECK(screen_) << "Server not grabbed";
527 // Setting the screen size will fail if any CRTC doesn't fit afterwards.
528 // At the same time, turning CRTCs off and back on uses up a lot of time.
529 // This function tries to be smart to avoid too many off/on cycles:
530 // - We disable all the CRTCs we won't need after the FB resize.
531 // - We set the new modes on CRTCs, if they fit in both the old and new
532 // FBs, and park them at (0,0)
533 // - We disable the CRTCs we will need but don't fit in the old FB. Those
534 // will be reenabled after the resize.
535 // We don't worry about the cached state of the outputs here since we are
536 // not interested in the state we are setting - we just try to get the CRTCs
537 // out of the way so we can rebuild the frame buffer.
538 for (int i = 0; i < screen_->ncrtc; ++i) {
539 // Default config is to disable the crtcs.
540 RRCrtc crtc = screen_->crtcs[i];
541 RRMode mode = None;
542 RROutput output = None;
543 const DisplayMode* mode_info = NULL;
544 for (ScopedVector<DisplaySnapshot>::const_iterator it =
545 cached_outputs_.begin();
546 it != cached_outputs_.end();
547 ++it) {
548 DisplaySnapshotX11* x11_output = static_cast<DisplaySnapshotX11*>(*it);
549 if (crtc == x11_output->crtc()) {
550 mode_info = x11_output->current_mode();
551 output = x11_output->output();
552 break;
556 if (mode_info) {
557 mode = static_cast<const DisplayModeX11*>(mode_info)->mode_id();
558 // In case our CRTC doesn't fit in common area of our current and about
559 // to be resized framebuffer, disable it.
560 // It'll get reenabled after we resize the framebuffer.
561 int max_width = std::min(DisplayWidth(display_,
562 DefaultScreen(display_)), new_size.width());
563 int max_height = std::min(DisplayHeight(display_,
564 DefaultScreen(display_)), new_size.height());
565 if (mode_info->size().width() > max_width ||
566 mode_info->size().height() > max_height) {
567 mode = None;
568 output = None;
569 mode_info = NULL;
573 ConfigureCrtc(crtc, mode, output, 0, 0);
577 bool NativeDisplayDelegateX11::IsOutputAspectPreservingScaling(RROutput id) {
578 bool ret = false;
580 Atom scaling_prop = XInternAtom(display_, "scaling mode", False);
581 Atom full_aspect_atom = XInternAtom(display_, "Full aspect", False);
582 if (scaling_prop == None || full_aspect_atom == None)
583 return false;
585 int nprop = 0;
586 Atom* props = XRRListOutputProperties(display_, id, &nprop);
587 for (int j = 0; j < nprop && !ret; j++) {
588 Atom prop = props[j];
589 if (scaling_prop == prop) {
590 unsigned char* values = NULL;
591 int actual_format;
592 unsigned long nitems;
593 unsigned long bytes_after;
594 Atom actual_type;
595 int success;
597 success = XRRGetOutputProperty(display_,
599 prop,
601 100,
602 False,
603 False,
604 AnyPropertyType,
605 &actual_type,
606 &actual_format,
607 &nitems,
608 &bytes_after,
609 &values);
610 if (success == Success && actual_type == XA_ATOM && actual_format == 32 &&
611 nitems == 1) {
612 Atom value = reinterpret_cast<Atom*>(values)[0];
613 if (full_aspect_atom == value)
614 ret = true;
616 if (values)
617 XFree(values);
620 if (props)
621 XFree(props);
623 return ret;
627 std::vector<ColorCalibrationProfile>
628 NativeDisplayDelegateX11::GetAvailableColorCalibrationProfiles(
629 const DisplaySnapshot& output) {
630 // TODO(mukai|marcheu): Checks the system data and fills the result.
631 // Note that the order would be Dynamic -> Standard -> Movie -> Reading.
632 return std::vector<ColorCalibrationProfile>();
635 bool NativeDisplayDelegateX11::SetColorCalibrationProfile(
636 const DisplaySnapshot& output,
637 ColorCalibrationProfile new_profile) {
638 const DisplaySnapshotX11& x11_output =
639 static_cast<const DisplaySnapshotX11&>(output);
641 XRRCrtcGamma* gamma_ramp = CreateGammaRampForProfile(x11_output, new_profile);
643 if (!gamma_ramp)
644 return false;
646 int gamma_ramp_size = XRRGetCrtcGammaSize(display_, x11_output.crtc());
647 XRRSetCrtcGamma(display_,
648 x11_output.crtc(),
649 ResampleGammaRamp(gamma_ramp, gamma_ramp_size));
650 XRRFreeGamma(gamma_ramp);
651 return true;
654 XRRCrtcGamma* NativeDisplayDelegateX11::CreateGammaRampForProfile(
655 const DisplaySnapshotX11& x11_output,
656 ColorCalibrationProfile new_profile) {
657 // TODO(mukai|marcheu): Creates the appropriate gamma ramp data from the
658 // profile enum. It would be served by the vendor.
659 return NULL;
662 void NativeDisplayDelegateX11::DrawBackground() {
663 if (!background_color_argb_)
664 return;
665 // Configuring CRTCs/Framebuffer clears the boot screen image. Paint the
666 // same background color after updating framebuffer to minimize the
667 // duration of black screen at boot time.
668 XColor color;
669 Colormap colormap = DefaultColormap(display_, 0);
670 // XColor uses 16 bits per color.
671 color.red = (background_color_argb_ & 0x00FF0000) >> 8;
672 color.green = (background_color_argb_ & 0x0000FF00);
673 color.blue = (background_color_argb_ & 0x000000FF) << 8;
674 color.flags = DoRed | DoGreen | DoBlue;
675 XAllocColor(display_, colormap, &color);
677 GC gc = XCreateGC(display_, window_, 0, 0);
678 XSetForeground(display_, gc, color.pixel);
679 XSetFillStyle(display_, gc, FillSolid);
680 int width = DisplayWidth(display_, DefaultScreen(display_));
681 int height = DisplayHeight(display_, DefaultScreen(display_));
682 XFillRectangle(display_, window_, gc, 0, 0, width, height);
683 XFreeGC(display_, gc);
684 XFreeColors(display_, colormap, &color.pixel, 1, 0);
687 } // namespace ui