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