Home | History | Annotate | Download | only in gfx
      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
      3 // found in the LICENSE file.
      4 
      5 #include "ui/gfx/color_utils.h"
      6 #include "ui/gfx/sys_color_change_listener.h"
      7 
      8 #if defined(OS_WIN)
      9 #include <windows.h>
     10 #endif
     11 
     12 #include "base/basictypes.h"
     13 #include "base/memory/singleton.h"
     14 #include "base/observer_list.h"
     15 #if defined(OS_WIN)
     16 #include "ui/base/win/singleton_hwnd.h"
     17 #endif
     18 
     19 namespace gfx {
     20 
     21 namespace {
     22 
     23 bool g_is_inverted_color_scheme = false;
     24 bool g_is_inverted_color_scheme_initialized = false;
     25 
     26 void UpdateInvertedColorScheme() {
     27 #if defined(OS_WIN)
     28   int foreground_luminance = color_utils::GetLuminanceForColor(
     29       color_utils::GetSysSkColor(COLOR_WINDOWTEXT));
     30   int background_luminance = color_utils::GetLuminanceForColor(
     31       color_utils::GetSysSkColor(COLOR_WINDOW));
     32   HIGHCONTRAST high_contrast = {0};
     33   high_contrast.cbSize = sizeof(HIGHCONTRAST);
     34   g_is_inverted_color_scheme =
     35       SystemParametersInfo(SPI_GETHIGHCONTRAST, 0, &high_contrast, 0) &&
     36       ((high_contrast.dwFlags & HCF_HIGHCONTRASTON) != 0) &&
     37       foreground_luminance > background_luminance;
     38   g_is_inverted_color_scheme_initialized = true;
     39 #endif
     40 }
     41 
     42 }  // namespace
     43 
     44 bool IsInvertedColorScheme() {
     45   if (!g_is_inverted_color_scheme_initialized)
     46     UpdateInvertedColorScheme();
     47   return g_is_inverted_color_scheme;
     48 }
     49 
     50 #if defined(OS_WIN)
     51 class SysColorChangeObserver : public ui::SingletonHwnd::Observer {
     52  public:
     53   static SysColorChangeObserver* GetInstance();
     54 
     55   void AddListener(SysColorChangeListener* listener);
     56   void RemoveListener(SysColorChangeListener* listener);
     57 
     58  private:
     59   friend struct DefaultSingletonTraits<SysColorChangeObserver>;
     60 
     61   SysColorChangeObserver();
     62   virtual ~SysColorChangeObserver();
     63 
     64   virtual void OnWndProc(HWND hwnd,
     65                          UINT message,
     66                          WPARAM wparam,
     67                          LPARAM lparam) OVERRIDE;
     68 
     69   ObserverList<SysColorChangeListener> listeners_;
     70 };
     71 
     72 // static
     73 SysColorChangeObserver* SysColorChangeObserver::GetInstance() {
     74   return Singleton<SysColorChangeObserver>::get();
     75 }
     76 
     77 SysColorChangeObserver::SysColorChangeObserver() {
     78   ui::SingletonHwnd::GetInstance()->AddObserver(this);
     79 }
     80 
     81 SysColorChangeObserver::~SysColorChangeObserver() {
     82   ui::SingletonHwnd::GetInstance()->RemoveObserver(this);
     83 }
     84 
     85 void SysColorChangeObserver::AddListener(SysColorChangeListener* listener) {
     86   listeners_.AddObserver(listener);
     87 }
     88 
     89 void SysColorChangeObserver::RemoveListener(SysColorChangeListener* listener) {
     90   listeners_.RemoveObserver(listener);
     91 }
     92 
     93 void SysColorChangeObserver::OnWndProc(HWND hwnd,
     94                                        UINT message,
     95                                        WPARAM wparam,
     96                                        LPARAM lparam) {
     97   if (message == WM_SYSCOLORCHANGE ||
     98       (message == WM_SETTINGCHANGE && wparam == SPI_SETHIGHCONTRAST)) {
     99     UpdateInvertedColorScheme();
    100     FOR_EACH_OBSERVER(SysColorChangeListener, listeners_, OnSysColorChange());
    101   }
    102 }
    103 #endif
    104 
    105 ScopedSysColorChangeListener::ScopedSysColorChangeListener(
    106     SysColorChangeListener* listener)
    107     : listener_(listener) {
    108 #if defined(OS_WIN)
    109   SysColorChangeObserver::GetInstance()->AddListener(listener_);
    110 #endif
    111 }
    112 
    113 ScopedSysColorChangeListener::~ScopedSysColorChangeListener() {
    114 #if defined(OS_WIN)
    115   SysColorChangeObserver::GetInstance()->RemoveListener(listener_);
    116 #endif
    117 }
    118 
    119 }  // namespace gfx
    120