blob: dcc283cef1a5249655ebc0093ca5f40ba692eded [file] [log] [blame]
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001/*
2 * Support for system colors
3 *
4 * Copyright David W. Metcalfe, 1993
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00005 * Copyright Alexandre Julliard, 1994
Alexandre Julliardf0b23541993-09-29 12:21:49 +00006 *
7 */
8
Alexandre Julliard02e90081998-01-04 17:49:09 +00009#include <assert.h>
Alexandre Julliardaca05781994-10-17 18:12:41 +000010#include <stdio.h>
Alexandre Julliardf0b23541993-09-29 12:21:49 +000011#include <stdlib.h>
Patrik Stridvall1ed4ecf1999-06-26 14:58:24 +000012
Jeremy Whited3e22d92000-02-10 19:03:02 +000013#include "windef.h"
14#include "wingdi.h"
Patrik Stridvall1ed4ecf1999-06-26 14:58:24 +000015#include "wine/winbase16.h"
16#include "wine/winuser16.h"
17#include "sysmetrics.h"
Marcus Meissner317af321999-02-17 13:51:06 +000018#include "winbase.h"
19#include "winuser.h"
Alexandre Julliard359f497e1999-07-04 16:02:24 +000020#include "debugtools.h"
Alexandre Julliardd37eb361997-07-20 16:23:21 +000021#include "tweak.h"
Juergen Schmiedd0d1f151999-04-11 11:39:17 +000022#include "winreg.h"
Andreas Mohr007fb242000-09-16 20:53:51 +000023#include "local.h"
24#include "gdi.h" /* sic */
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000025
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000026DEFAULT_DEBUG_CHANNEL(syscolor)
27
Alexandre Julliardd90840e1996-06-11 16:02:08 +000028static const char * const DefSysColors[] =
Alexandre Julliardf0b23541993-09-29 12:21:49 +000029{
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000030 "Scrollbar", "224 224 224", /* COLOR_SCROLLBAR */
31 "Background", "192 192 192", /* COLOR_BACKGROUND */
32 "ActiveTitle", "0 64 128", /* COLOR_ACTIVECAPTION */
33 "InactiveTitle", "255 255 255", /* COLOR_INACTIVECAPTION */
Alexandre Julliard17216f51997-10-12 16:30:17 +000034 "Menu", "255 255 255", /* COLOR_MENU */
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000035 "Window", "255 255 255", /* COLOR_WINDOW */
36 "WindowFrame", "0 0 0", /* COLOR_WINDOWFRAME */
37 "MenuText", "0 0 0", /* COLOR_MENUTEXT */
38 "WindowText", "0 0 0", /* COLOR_WINDOWTEXT */
39 "TitleText", "255 255 255", /* COLOR_CAPTIONTEXT */
40 "ActiveBorder", "128 128 128", /* COLOR_ACTIVEBORDER */
41 "InactiveBorder", "255 255 255", /* COLOR_INACTIVEBORDER */
42 "AppWorkspace", "255 255 232", /* COLOR_APPWORKSPACE */
Alexandre Julliardc7c217b1998-04-13 12:21:30 +000043 "Hilight", "224 224 224", /* COLOR_HIGHLIGHT */
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000044 "HilightText", "0 0 0", /* COLOR_HIGHLIGHTTEXT */
45 "ButtonFace", "192 192 192", /* COLOR_BTNFACE */
46 "ButtonShadow", "128 128 128", /* COLOR_BTNSHADOW */
47 "GrayText", "192 192 192", /* COLOR_GRAYTEXT */
48 "ButtonText", "0 0 0", /* COLOR_BTNTEXT */
49 "InactiveTitleText", "0 0 0", /* COLOR_INACTIVECAPTIONTEXT */
Alexandre Julliard77b99181997-09-14 17:17:23 +000050 "ButtonHilight", "255 255 255", /* COLOR_BTNHIGHLIGHT */
51 "3DDarkShadow", "32 32 32", /* COLOR_3DDKSHADOW */
52 "3DLight", "192 192 192", /* COLOR_3DLIGHT */
53 "InfoText", "0 0 0", /* COLOR_INFOTEXT */
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000054 "InfoBackground", "255 255 192", /* COLOR_INFOBK */
55 "AlternateButtonFace", "184 180 184", /* COLOR_ALTERNATEBTNFACE */
56 "HotTrackingColor", "0 0 255", /* COLOR_HOTLIGHT */
57 "GradientActiveTitle", "16 132 208", /* COLOR_GRADIENTACTIVECAPTION */
58 "GradientInactiveTitle", "184 180 184" /* COLOR_GRADIENTINACTIVECAPTION */
Alexandre Julliardf0b23541993-09-29 12:21:49 +000059};
60
Alexandre Julliardd37eb361997-07-20 16:23:21 +000061static const char * const DefSysColors95[] =
62{
Alexandre Julliarddadf78f1998-05-17 17:13:43 +000063 "Scrollbar", "223 223 223", /* COLOR_SCROLLBAR */
Alexandre Julliardd37eb361997-07-20 16:23:21 +000064 "Background", "192 192 192", /* COLOR_BACKGROUND */
Alexandre Julliard642d3131998-07-12 19:29:36 +000065 "ActiveTitle", "0 0 128", /* COLOR_ACTIVECAPTION */
66 "InactiveTitle", "128 128 128", /* COLOR_INACTIVECAPTION */
Alexandre Julliardd37eb361997-07-20 16:23:21 +000067 "Menu", "192 192 192", /* COLOR_MENU */
68 "Window", "255 255 255", /* COLOR_WINDOW */
69 "WindowFrame", "0 0 0", /* COLOR_WINDOWFRAME */
70 "MenuText", "0 0 0", /* COLOR_MENUTEXT */
71 "WindowText", "0 0 0", /* COLOR_WINDOWTEXT */
72 "TitleText", "255 255 255", /* COLOR_CAPTIONTEXT */
Alexandre Julliard642d3131998-07-12 19:29:36 +000073 "ActiveBorder", "192 192 192", /* COLOR_ACTIVEBORDER */
74 "InactiveBorder", "192 192 192", /* COLOR_INACTIVEBORDER */
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +000075 "AppWorkspace", "128 128 128", /* COLOR_APPWORKSPACE */
Alexandre Julliard642d3131998-07-12 19:29:36 +000076 "Hilight", "0 0 128", /* COLOR_HIGHLIGHT */
77 "HilightText", "255 255 255", /* COLOR_HIGHLIGHTTEXT */
Alexandre Julliardd37eb361997-07-20 16:23:21 +000078 "ButtonFace", "192 192 192", /* COLOR_BTNFACE */
79 "ButtonShadow", "128 128 128", /* COLOR_BTNSHADOW */
Gerard Patelfd087371999-07-23 19:18:37 +000080 "GrayText", "128 128 128", /* COLOR_GRAYTEXT */
Alexandre Julliardd37eb361997-07-20 16:23:21 +000081 "ButtonText", "0 0 0", /* COLOR_BTNTEXT */
82 "InactiveTitleText", "0 0 0", /* COLOR_INACTIVECAPTIONTEXT */
Alexandre Julliard77b99181997-09-14 17:17:23 +000083 "ButtonHilight", "255 255 255", /* COLOR_BTNHIGHLIGHT */
Alexandre Julliarddadf78f1998-05-17 17:13:43 +000084 "3DDarkShadow", "0 0 0", /* COLOR_3DDKSHADOW */
Noomen Hamza24d4ebf1999-10-13 13:47:01 +000085 "3DLight", "192 192 192", /* COLOR_3DLIGHT */
Alexandre Julliard77b99181997-09-14 17:17:23 +000086 "InfoText", "0 0 0", /* COLOR_INFOTEXT */
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000087 "InfoBackground", "255 255 192", /* COLOR_INFOBK */
88 "AlternateButtonFace", "184 180 184", /* COLOR_ALTERNATEBTNFACE */
89 "HotTrackingColor", "0 0 255", /* COLOR_HOTLIGHT */
90 "GradientActiveTitle", "16 132 208", /* COLOR_GRADIENTACTIVECAPTION */
91 "GradientInactiveTitle", "184 180 184" /* COLOR_GRADIENTINACTIVECAPTION */
Alexandre Julliardd37eb361997-07-20 16:23:21 +000092};
93
94
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000095#define NUM_SYS_COLORS (COLOR_GRADIENTINACTIVECAPTION+1)
Alexandre Julliardf0b23541993-09-29 12:21:49 +000096
97static COLORREF SysColors[NUM_SYS_COLORS];
Alexandre Julliarda3960291999-02-26 11:11:13 +000098static HBRUSH SysColorBrushes[NUM_SYS_COLORS];
99static HPEN SysColorPens[NUM_SYS_COLORS];
Alexandre Julliardf0b23541993-09-29 12:21:49 +0000100
Alexandre Julliardf7207251994-07-23 07:57:48 +0000101#define MAKE_SOLID(color) \
Alexandre Julliarda3960291999-02-26 11:11:13 +0000102 (PALETTEINDEX(GetNearestPaletteIndex(STOCK_DEFAULT_PALETTE,(color))))
Alexandre Julliardf0b23541993-09-29 12:21:49 +0000103
Andreas Mohr007fb242000-09-16 20:53:51 +0000104
105/*************************************************************************
106 * SYSCOLOR_MakeObjectSystem
107 *
108 * OK, now for a very ugly hack.
109 * USER somehow has to tell GDI that its system brushes and pens are
110 * non-deletable.
111 * We don't want to export a function from GDI doing this for us,
112 * so we just do that ourselves by "wildly flipping some bits in memory".
113 * For a description of the GDI object magics and their flags,
114 * see "Undocumented Windows" (wrong about the OBJECT_NOSYSTEM flag, though).
115 */
116static void SYSCOLOR_MakeObjectSystem( HGDIOBJ handle, BOOL set)
117{
118 static WORD GDI_heap_sel = 0;
119 LPWORD ptr;
120
121 if (!GDI_heap_sel)
122 {
123 GDI_heap_sel = LoadLibrary16("gdi");
124 FreeLibrary16(GDI_heap_sel);
125 }
126
127 ptr = (LPWORD)LOCAL_Lock(GDI_heap_sel, handle);
128
129 /* touch the "system" bit of the wMagic field of a GDIOBJHDR */
130 if (set)
131 *(ptr+1) &= ~OBJECT_NOSYSTEM;
132 else
133 *(ptr+1) |= OBJECT_NOSYSTEM;
134 LOCAL_Unlock( GDI_heap_sel, handle );
135}
136
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000137/*************************************************************************
Alexandre Julliard58199531994-04-21 01:20:00 +0000138 * SYSCOLOR_SetColor
139 */
140static void SYSCOLOR_SetColor( int index, COLORREF color )
141{
Alexandre Julliard77b99181997-09-14 17:17:23 +0000142 if (index < 0 || index >= NUM_SYS_COLORS) return;
Alexandre Julliard58199531994-04-21 01:20:00 +0000143 SysColors[index] = color;
Andreas Mohr007fb242000-09-16 20:53:51 +0000144 if (SysColorBrushes[index])
145 {
146 SYSCOLOR_MakeObjectSystem(SysColorBrushes[index], FALSE);
147 DeleteObject( SysColorBrushes[index] );
148 }
Alexandre Julliarda3960291999-02-26 11:11:13 +0000149 SysColorBrushes[index] = CreateSolidBrush( color );
Andreas Mohr007fb242000-09-16 20:53:51 +0000150 SYSCOLOR_MakeObjectSystem(SysColorBrushes[index], TRUE);
151
152 if (SysColorPens[index])
153 {
154 SYSCOLOR_MakeObjectSystem(SysColorBrushes[index], FALSE);
155 DeleteObject( SysColorPens[index] );
156 }
Alexandre Julliarda3960291999-02-26 11:11:13 +0000157 SysColorPens[index] = CreatePen( PS_SOLID, 1, color );
Andreas Mohr007fb242000-09-16 20:53:51 +0000158 SYSCOLOR_MakeObjectSystem(SysColorBrushes[index], TRUE);
Alexandre Julliard58199531994-04-21 01:20:00 +0000159}
160
161
162/*************************************************************************
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000163 * SYSCOLOR_Init
164 */
Alexandre Julliard234bc241994-12-10 13:02:28 +0000165void SYSCOLOR_Init(void)
Alexandre Julliardf0b23541993-09-29 12:21:49 +0000166{
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000167 int i, r, g, b;
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000168 const char * const *p;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000169 char buffer[100];
Gerard Patelb7a4f461999-04-22 09:58:13 +0000170 BOOL bOk = FALSE, bNoReg = FALSE;
171 HKEY hKey;
Alexandre Julliardf0b23541993-09-29 12:21:49 +0000172
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000173 p = (TWEAK_WineLook == WIN31_LOOK) ? DefSysColors : DefSysColors95;
Juergen Schmiedd0d1f151999-04-11 11:39:17 +0000174
175 /* first, try to read the values from the registry */
Marcus Meissner1c5777a1999-12-11 23:02:50 +0000176 if (RegCreateKeyExA(HKEY_CURRENT_USER, "Control Panel\\Colors", 0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, 0))
177 bNoReg = TRUE;
178 for (i = 0; i < NUM_SYS_COLORS; i++)
179 { bOk = FALSE;
Juergen Schmied4ab79f91999-04-18 09:32:38 +0000180
Marcus Meissner1c5777a1999-12-11 23:02:50 +0000181 /* first try, registry */
Juergen Schmied4ab79f91999-04-18 09:32:38 +0000182 if (!bNoReg)
Marcus Meissner1c5777a1999-12-11 23:02:50 +0000183 {
184 DWORD dwDataSize = sizeof(buffer);
185 if (!(RegQueryValueExA(hKey,(LPSTR)p[i*2], 0, 0, buffer, &dwDataSize)))
186 if (sscanf( buffer, "%d %d %d", &r, &g, &b ) == 3)
187 bOk = TRUE;
188 }
Juergen Schmiedd0d1f151999-04-11 11:39:17 +0000189
Marcus Meissner1c5777a1999-12-11 23:02:50 +0000190 /* second try, win.ini */
191 if (!bOk)
192 { GetProfileStringA( "colors", p[i*2], p[i*2+1], buffer, 100 );
193 if (sscanf( buffer, " %d %d %d", &r, &g, &b ) == 3)
194 bOk = TRUE;
195 }
196
197 /* last chance, take the default */
198 if (!bOk)
199 { int iNumColors = sscanf( p[i*2+1], " %d %d %d", &r, &g, &b );
200 assert (iNumColors==3);
201 }
202
203 SYSCOLOR_SetColor( i, RGB(r,g,b) );
204 }
205 if (!bNoReg)
206 RegCloseKey(hKey);
Alexandre Julliardf0b23541993-09-29 12:21:49 +0000207}
208
209
210/*************************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000211 * GetSysColor16 (USER.180)
Alexandre Julliardf0b23541993-09-29 12:21:49 +0000212 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000213COLORREF WINAPI GetSysColor16( INT16 nIndex )
Alexandre Julliardf0b23541993-09-29 12:21:49 +0000214{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000215 return GetSysColor (nIndex);
Alexandre Julliardf0b23541993-09-29 12:21:49 +0000216}
217
218
219/*************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +0000220 * GetSysColor (USER32.289)
Alexandre Julliardf0b23541993-09-29 12:21:49 +0000221 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000222COLORREF WINAPI GetSysColor( INT nIndex )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000223{
Alexandre Julliard77b99181997-09-14 17:17:23 +0000224 if (nIndex >= 0 && nIndex < NUM_SYS_COLORS)
225 return SysColors[nIndex];
226 else
227 return 0;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000228}
Alexandre Julliardf0b23541993-09-29 12:21:49 +0000229
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000230
231/*************************************************************************
232 * SetSysColors16 (USER.181)
233 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000234VOID WINAPI SetSysColors16( INT16 nChanges, const INT16 *lpSysColor,
Alexandre Julliard77b99181997-09-14 17:17:23 +0000235 const COLORREF *lpColorValues )
Alexandre Julliardf0b23541993-09-29 12:21:49 +0000236{
Alexandre Julliardf0b23541993-09-29 12:21:49 +0000237 int i;
238
Alexandre Julliardf0b23541993-09-29 12:21:49 +0000239 for (i = 0; i < nChanges; i++)
240 {
Alexandre Julliard58199531994-04-21 01:20:00 +0000241 SYSCOLOR_SetColor( lpSysColor[i], lpColorValues[i] );
Alexandre Julliardf0b23541993-09-29 12:21:49 +0000242 }
243
244 /* Send WM_SYSCOLORCHANGE message to all windows */
245
Alexandre Julliarda3960291999-02-26 11:11:13 +0000246 SendMessageA( HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0 );
Alexandre Julliardf0b23541993-09-29 12:21:49 +0000247
248 /* Repaint affected portions of all visible windows */
249
Alexandre Julliarda3960291999-02-26 11:11:13 +0000250 RedrawWindow( GetDesktopWindow(), NULL, 0,
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000251 RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN );
252}
253
254
255/*************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +0000256 * SetSysColors (USER32.505)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000257 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000258BOOL WINAPI SetSysColors( INT nChanges, const INT *lpSysColor,
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000259 const COLORREF *lpColorValues )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000260{
261 int i;
262
263 for (i = 0; i < nChanges; i++)
264 {
265 SYSCOLOR_SetColor( lpSysColor[i], lpColorValues[i] );
266 }
267
268 /* Send WM_SYSCOLORCHANGE message to all windows */
269
Alexandre Julliarda3960291999-02-26 11:11:13 +0000270 SendMessageA( HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0 );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000271
272 /* Repaint affected portions of all visible windows */
273
Alexandre Julliarda3960291999-02-26 11:11:13 +0000274 RedrawWindow( GetDesktopWindow(), NULL, 0,
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000275 RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN );
276 return TRUE;
Alexandre Julliardf0b23541993-09-29 12:21:49 +0000277}
Alexandre Julliard02e90081998-01-04 17:49:09 +0000278
279
280/***********************************************************************
281 * GetSysColorBrush16 (USER.281)
282 */
283HBRUSH16 WINAPI GetSysColorBrush16( INT16 index )
284{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000285 return (HBRUSH16)GetSysColorBrush(index);
Alexandre Julliard02e90081998-01-04 17:49:09 +0000286}
287
288
289/***********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +0000290 * GetSysColorBrush (USER32.290)
Alexandre Julliard02e90081998-01-04 17:49:09 +0000291 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000292HBRUSH WINAPI GetSysColorBrush( INT index )
Alexandre Julliard02e90081998-01-04 17:49:09 +0000293{
294 if (0 <= index && index < NUM_SYS_COLORS)
295 return SysColorBrushes[index];
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000296 WARN("Unknown index(%d)\n", index );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000297 return GetStockObject(LTGRAY_BRUSH);
Alexandre Julliard02e90081998-01-04 17:49:09 +0000298}
299
300
301/***********************************************************************
302 * GetSysColorPen16 (Not a Windows API)
303 */
304HPEN16 WINAPI GetSysColorPen16( INT16 index )
305{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000306 return (HPEN16)GetSysColorPen(index);
Alexandre Julliard02e90081998-01-04 17:49:09 +0000307}
308
309
310/***********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +0000311 * GetSysColorPen (Not a Windows API)
Alexandre Julliard02e90081998-01-04 17:49:09 +0000312 *
313 * This function is new to the Wine lib -- it does not exist in
314 * Windows. However, it is a natural complement for GetSysColorBrush
315 * in the Win32 API and is needed quite a bit inside Wine.
316 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000317HPEN WINAPI GetSysColorPen( INT index )
Alexandre Julliard02e90081998-01-04 17:49:09 +0000318{
319 /* We can assert here, because this function is internal to Wine */
320 assert (0 <= index && index < NUM_SYS_COLORS);
321 return SysColorPens[index];
322
323}