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 20namespace gfx { 21 22namespace { 23 24bool g_is_inverted_color_scheme = false; 25bool g_is_inverted_color_scheme_initialized = false; 26 27void 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 45bool 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) 52class 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 74SysColorChangeObserver* SysColorChangeObserver::GetInstance() { 75 return Singleton<SysColorChangeObserver>::get(); 76} 77 78SysColorChangeObserver::SysColorChangeObserver() { 79 gfx::SingletonHwnd::GetInstance()->AddObserver(this); 80} 81 82SysColorChangeObserver::~SysColorChangeObserver() { 83 gfx::SingletonHwnd::GetInstance()->RemoveObserver(this); 84} 85 86void SysColorChangeObserver::AddListener(SysColorChangeListener* listener) { 87 listeners_.AddObserver(listener); 88} 89 90void SysColorChangeObserver::RemoveListener(SysColorChangeListener* listener) { 91 listeners_.RemoveObserver(listener); 92} 93 94void 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 106ScopedSysColorChangeListener::ScopedSysColorChangeListener( 107 SysColorChangeListener* listener) 108 : listener_(listener) { 109#if defined(OS_WIN) 110 SysColorChangeObserver::GetInstance()->AddListener(listener_); 111#endif 112} 113 114ScopedSysColorChangeListener::~ScopedSysColorChangeListener() { 115#if defined(OS_WIN) 116 SysColorChangeObserver::GetInstance()->RemoveListener(listener_); 117#endif 118} 119 120} // namespace gfx 121