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