From 3448a84cac437f66bf7bdd833a6ce5026fddd4cc Mon Sep 17 00:00:00 2001 From: Myah Caron Date: Fri, 22 Sep 2023 20:41:23 +0000 Subject: [PATCH] windows.ui: Support accent colors in uisettings3_GetColorValue. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55640 Signed-off-by: Myah Caron --- dlls/windows.ui/tests/uisettings.c | 95 ++++++++++++++++++++++++++++++ dlls/windows.ui/uisettings.c | 64 ++++++++++++++++++-- 2 files changed, 154 insertions(+), 5 deletions(-) diff --git a/dlls/windows.ui/tests/uisettings.c b/dlls/windows.ui/tests/uisettings.c index 8d739cb7bef..40588f0000f 100644 --- a/dlls/windows.ui/tests/uisettings.c +++ b/dlls/windows.ui/tests/uisettings.c @@ -75,6 +75,45 @@ static DWORD set_app_theme( DWORD mode ) return ret; } +static BOOL get_accent_palette( DWORD *colors, DWORD *len ) +{ + BOOL ret = TRUE; + DWORD type; + HKEY hkey; + + if (RegOpenKeyExW( HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Accent", 0, KEY_QUERY_VALUE, &hkey )) return FALSE; + if (RegQueryValueExW( hkey, L"AccentPalette", NULL, &type, (BYTE *)colors, len ) || type != REG_BINARY) ret = FALSE; + RegCloseKey( hkey ); + return ret; +} + +static BOOL delete_accent_palette(void) +{ + BOOL ret = TRUE; + HRESULT res; + HKEY hkey; + + res = RegOpenKeyExW( HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Accent", 0, KEY_SET_VALUE, &hkey ); + if (res != 0) return res == ERROR_FILE_NOT_FOUND; + + res = RegDeleteValueW( hkey, L"AccentPalette" ); + if (res != 0 && res != ERROR_FILE_NOT_FOUND) ret = FALSE; + + RegCloseKey( hkey ); + return ret; +} + +static DWORD set_accent_palette( DWORD *colors, DWORD len ) +{ + DWORD ret = 1; + HKEY hkey; + + if (RegOpenKeyExW( HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Accent", 0, KEY_SET_VALUE, &hkey )) return 0; + if (RegSetValueExW( hkey, L"AccentPalette", 0, REG_BINARY, (const BYTE *)&colors, len )) ret = 0; + RegCloseKey( hkey ); + return ret; +} + static void reset_color( Color *value ) { value->A = 1; @@ -83,6 +122,60 @@ static void reset_color( Color *value ) value->B = 1; } +static BOOL compare_dword_color( Color color, DWORD dword ) +{ + return (color.R == (dword & 0xFF) && color.G == ((dword >> 8) & 0xFF) && color.B == ((dword >> 16) & 0xFF)); +} + +static void test_single_accent( IUISettings3 *uisettings3, UIColorType type, DWORD expected ) +{ + Color value; + HRESULT hr; + BOOL result; + + reset_color( &value ); + hr = IUISettings3_GetColorValue( uisettings3, type, &value ); + ok( hr == S_OK, "GetColorValue returned %#lx\n", hr ); + + result = compare_dword_color( value, expected ); + ok( result, "got unexpected value.A == %d value.R == %d value.G == %d value.B == %d (type = %d)\n", value.A, value.R, value.G, value.B, type ); +} + +static void test_AccentColor( IUISettings3 *uisettings3 ) +{ + DWORD default_palette[8]; + DWORD default_palette_len = sizeof(default_palette); + DWORD accent_palette[8]; + DWORD accent_palette_len = sizeof(accent_palette); + + if (!get_accent_palette( default_palette, &default_palette_len )) default_palette_len = 0; + + /* deleting AccentPalette fills a default value */ + ok( delete_accent_palette(), "failed to delete AccentPalette key.\n"); + ok( !get_accent_palette( accent_palette, &accent_palette_len ), "AccentPalette should not be available.\n" ); + + test_single_accent( uisettings3, UIColorType_Accent, 0x00d77800 ); + ok( get_accent_palette( accent_palette, &accent_palette_len ), "failed to retrieve AccentPalette key.\n" ); + + /* default values */ + test_single_accent( uisettings3, UIColorType_AccentDark1, 0x009e5a00 ); + test_single_accent( uisettings3, UIColorType_AccentDark2, 0x00754200 ); + test_single_accent( uisettings3, UIColorType_AccentDark3, 0x00422600 ); + test_single_accent( uisettings3, UIColorType_AccentLight1, 0x00e39c42 ); + test_single_accent( uisettings3, UIColorType_AccentLight2, 0x00edb976 ); + test_single_accent( uisettings3, UIColorType_AccentLight3, 0x00ffd8a6 ); + + test_single_accent( uisettings3, UIColorType_Accent, accent_palette[3] ); + test_single_accent( uisettings3, UIColorType_AccentDark1, accent_palette[4] ); + test_single_accent( uisettings3, UIColorType_AccentDark2, accent_palette[5] ); + test_single_accent( uisettings3, UIColorType_AccentDark3, accent_palette[6] ); + test_single_accent( uisettings3, UIColorType_AccentLight1, accent_palette[2] ); + test_single_accent( uisettings3, UIColorType_AccentLight2, accent_palette[1] ); + test_single_accent( uisettings3, UIColorType_AccentLight3, accent_palette[0] ); + + if (default_palette_len) set_accent_palette( default_palette, default_palette_len ); +} + static void test_UISettings(void) { static const WCHAR *uisettings_name = L"Windows.UI.ViewManagement.UISettings"; @@ -126,6 +219,8 @@ static void test_UISettings(void) check_interface( inspectable, &IID_IAgileObject, TRUE ); + test_AccentColor( uisettings3 ); + default_theme = get_app_theme(); /* Light Theme */ diff --git a/dlls/windows.ui/uisettings.c b/dlls/windows.ui/uisettings.c index 041388da33b..b36194a2ac3 100644 --- a/dlls/windows.ui/uisettings.c +++ b/dlls/windows.ui/uisettings.c @@ -266,6 +266,40 @@ static DWORD get_app_theme(void) return ret; } +static DWORD initialize_accent_palette( HKEY hkey, DWORD offset ) +{ + DWORD palette[7] = { 0x00ffd8a6, 0x00edb976, 0x00e39c42, 0x00d77800, 0x009e5a00, 0x00754200, 0x00422600 }; + DWORD len = sizeof(palette); + + RegSetValueExW( hkey, L"AccentPalette", 0, REG_BINARY, (const BYTE *)&palette, len ); + return palette[offset]; +} + +static void dword_to_color( DWORD color, Color *out ) +{ + out->R = color & 0xFF; + out->G = (color >> 8) & 0xFF; + out->B = (color >> 16) & 0xFF; + out->A = 0xFF; +} + +static void get_accent_palette_color( DWORD offset, Color *out ) +{ + DWORD palette[7]; + DWORD ret = 0, len = sizeof(palette), type; + HKEY hkey; + + if (!RegCreateKeyW( HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Accent", &hkey )) + { + if (RegQueryValueExW( hkey, L"AccentPalette", NULL, &type, (BYTE *)&palette, &len ) || type != REG_BINARY) + ret = initialize_accent_palette( hkey, offset ); + else + ret = palette[offset]; + RegCloseKey( hkey ); + } + dword_to_color( ret, out ); +} + static void set_color_value( BYTE a, BYTE r, BYTE g, BYTE b, Color *out ) { out->A = a; @@ -283,19 +317,39 @@ static HRESULT WINAPI uisettings3_GetColorValue( IUISettings3 *iface, UIColorTyp switch (type) { case UIColorType_Foreground: + theme = get_app_theme(); + set_color_value( 255, theme ? 0 : 255, theme ? 0 : 255, theme ? 0 : 255, value ); + break; case UIColorType_Background: theme = get_app_theme(); + set_color_value( 255, theme ? 255 : 0, theme ? 255 : 0, theme ? 255 : 0, value ); + break; + case UIColorType_Accent: + get_accent_palette_color( 3, value ); + break; + case UIColorType_AccentDark1: + get_accent_palette_color( 4, value ); + break; + case UIColorType_AccentDark2: + get_accent_palette_color( 5, value ); + break; + case UIColorType_AccentDark3: + get_accent_palette_color( 6, value ); + break; + case UIColorType_AccentLight1: + get_accent_palette_color( 2, value ); + break; + case UIColorType_AccentLight2: + get_accent_palette_color( 1, value ); + break; + case UIColorType_AccentLight3: + get_accent_palette_color( 0, value ); break; default: FIXME( "type %d not implemented.\n", type ); return E_NOTIMPL; } - if (type == UIColorType_Foreground) - set_color_value( 255, theme ? 0 : 255, theme ? 0 : 255, theme ? 0 : 255, value ); - else - set_color_value( 255, theme ? 255 : 0, theme ? 255 : 0, theme ? 255 : 0, value ); - TRACE( "Returning value.A = %d, value.R = %d, value.G = %d, value.B = %d\n", value->A, value->R, value->G, value->B ); return S_OK; }