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