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