1c2c66affSColin Finck /*
2c2c66affSColin Finck * Unit test suite for palettes
3c2c66affSColin Finck *
4c2c66affSColin Finck * Copyright 2005 Glenn Wurster
5c2c66affSColin Finck *
6c2c66affSColin Finck * This library is free software; you can redistribute it and/or
7c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
8c2c66affSColin Finck * License as published by the Free Software Foundation; either
9c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
10c2c66affSColin Finck *
11c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
12c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
13c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14c2c66affSColin Finck * Lesser General Public License for more details.
15c2c66affSColin Finck *
16c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
17c2c66affSColin Finck * License along with this library; if not, write to the Free Software
18c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19c2c66affSColin Finck */
20c2c66affSColin Finck
21*ff449c5fSAmine Khaldi #include <stdarg.h>
22*ff449c5fSAmine Khaldi
23*ff449c5fSAmine Khaldi #include "windef.h"
24*ff449c5fSAmine Khaldi #include "winbase.h"
25*ff449c5fSAmine Khaldi #include "wingdi.h"
26*ff449c5fSAmine Khaldi #include "winuser.h"
27*ff449c5fSAmine Khaldi #include "mmsystem.h"
28*ff449c5fSAmine Khaldi
29*ff449c5fSAmine Khaldi #include "wine/test.h"
30c2c66affSColin Finck
31c2c66affSColin Finck static const PALETTEENTRY logpalettedata[8] = {
32c2c66affSColin Finck { 0x10, 0x20, 0x30, PC_NOCOLLAPSE },
33c2c66affSColin Finck { 0x20, 0x30, 0x40, PC_NOCOLLAPSE },
34c2c66affSColin Finck { 0x30, 0x40, 0x50, PC_NOCOLLAPSE },
35c2c66affSColin Finck { 0x40, 0x50, 0x60, PC_NOCOLLAPSE },
36c2c66affSColin Finck { 0x50, 0x60, 0x70, PC_NOCOLLAPSE },
37c2c66affSColin Finck { 0x60, 0x70, 0x80, PC_NOCOLLAPSE },
38c2c66affSColin Finck { 0x70, 0x80, 0x90, PC_NOCOLLAPSE },
39c2c66affSColin Finck { 0x80, 0x90, 0xA0, PC_NOCOLLAPSE },
40c2c66affSColin Finck };
41c2c66affSColin Finck
test_DIB_PAL_COLORS(void)42c2c66affSColin Finck static void test_DIB_PAL_COLORS(void) {
43c2c66affSColin Finck HDC hdc = GetDC( NULL );
44c2c66affSColin Finck HDC memhdc = CreateCompatibleDC( hdc );
45c2c66affSColin Finck HBITMAP hbmp, hbmpOld;
46c2c66affSColin Finck char bmpbuf[sizeof(BITMAPINFO) + 10 * sizeof(WORD)];
47c2c66affSColin Finck PBITMAPINFO bmp = (PBITMAPINFO)bmpbuf;
48c2c66affSColin Finck WORD * bmpPalPtr;
49c2c66affSColin Finck char logpalettebuf[sizeof(LOGPALETTE) + sizeof(logpalettedata)];
50c2c66affSColin Finck PLOGPALETTE logpalette = (PLOGPALETTE)logpalettebuf;
51c2c66affSColin Finck HPALETTE hpal, hpalOld;
52c2c66affSColin Finck COLORREF setColor, chkColor, getColor;
53c2c66affSColin Finck int i;
54c2c66affSColin Finck
55c2c66affSColin Finck /* Initialize the logical palette with a few colours */
56c2c66affSColin Finck logpalette->palVersion = 0x300;
57c2c66affSColin Finck logpalette->palNumEntries = 8;
58c2c66affSColin Finck memcpy( logpalette->palPalEntry, logpalettedata, sizeof(logpalettedata) );
59c2c66affSColin Finck hpal = CreatePalette( logpalette );
60c2c66affSColin Finck hpalOld = SelectPalette( memhdc, hpal, FALSE );
61c2c66affSColin Finck ok( hpalOld != NULL, "error=%d\n", GetLastError() );
62c2c66affSColin Finck
63c2c66affSColin Finck /* Create a DIB BMP which references colours in the logical palette */
64c2c66affSColin Finck memset( bmp, 0x00, sizeof(BITMAPINFO) );
65c2c66affSColin Finck bmp->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
66c2c66affSColin Finck bmp->bmiHeader.biWidth = 1;
67c2c66affSColin Finck bmp->bmiHeader.biHeight = 1;
68c2c66affSColin Finck bmp->bmiHeader.biPlanes = 1;
69c2c66affSColin Finck bmp->bmiHeader.biBitCount = 8;
70c2c66affSColin Finck bmp->bmiHeader.biCompression = BI_RGB;
71c2c66affSColin Finck bmp->bmiHeader.biClrUsed = 10;
72c2c66affSColin Finck bmp->bmiHeader.biClrImportant = 0;
73c2c66affSColin Finck bmpPalPtr = (WORD *)&bmp->bmiColors;
74c2c66affSColin Finck for( i = 0; i < 8; i++ ) {
75c2c66affSColin Finck *bmpPalPtr++ = i;
76c2c66affSColin Finck }
77c2c66affSColin Finck *bmpPalPtr++ = 8; /* Pointer to logical palette index just outside range */
78c2c66affSColin Finck *bmpPalPtr++ = 19; /* Pointer to bad logical palette index */
79c2c66affSColin Finck
80c2c66affSColin Finck hbmp = CreateDIBSection( memhdc, bmp, DIB_PAL_COLORS, 0, 0, 0 );
81c2c66affSColin Finck ok( hbmp != NULL, "error=%d\n", GetLastError() );
82c2c66affSColin Finck hbmpOld = SelectObject( memhdc, hbmp );
83c2c66affSColin Finck ok( hbmpOld != NULL, "error=%d\n", GetLastError() );
84c2c66affSColin Finck
85c2c66affSColin Finck /* Test with a RGB to DIB_PAL_COLORS */
86c2c66affSColin Finck setColor = RGB( logpalettedata[1].peRed, logpalettedata[1].peGreen, logpalettedata[1].peBlue );
87c2c66affSColin Finck SetPixel( memhdc, 0, 0, setColor );
88c2c66affSColin Finck chkColor = RGB( logpalettedata[1].peRed, logpalettedata[1].peGreen, logpalettedata[1].peBlue );
89c2c66affSColin Finck getColor = GetPixel( memhdc, 0, 0 );
90c2c66affSColin Finck ok( getColor == chkColor, "getColor=%08X\n", (UINT)getColor );
91c2c66affSColin Finck
92c2c66affSColin Finck /* Test with a valid DIBINDEX to DIB_PAL_COLORS */
93c2c66affSColin Finck setColor = DIBINDEX( 2 );
94c2c66affSColin Finck SetPixel( memhdc, 0, 0, setColor );
95c2c66affSColin Finck chkColor = RGB( logpalettedata[2].peRed, logpalettedata[2].peGreen, logpalettedata[2].peBlue );
96c2c66affSColin Finck getColor = GetPixel( memhdc, 0, 0 );
97c2c66affSColin Finck ok( getColor == chkColor, "getColor=%08X\n", (UINT)getColor );
98c2c66affSColin Finck
99c2c66affSColin Finck /* Test with an invalid DIBINDEX to DIB_PAL_COLORS */
100c2c66affSColin Finck setColor = DIBINDEX( 12 );
101c2c66affSColin Finck SetPixel( memhdc, 0, 0, setColor );
102c2c66affSColin Finck chkColor = RGB( 0, 0, 0 );
103c2c66affSColin Finck getColor = GetPixel( memhdc, 0, 0 );
104c2c66affSColin Finck ok( getColor == chkColor, "getColor=%08X\n", (UINT)getColor );
105c2c66affSColin Finck
106c2c66affSColin Finck /* Test for double wraparound on logical palette references from */
107c2c66affSColin Finck /* DIBINDEX by DIB_PAL_COLORS. */
108c2c66affSColin Finck setColor = DIBINDEX( 9 );
109c2c66affSColin Finck SetPixel( memhdc, 0, 0, setColor );
110c2c66affSColin Finck chkColor = RGB( logpalettedata[3].peRed, logpalettedata[3].peGreen, logpalettedata[3].peBlue );
111c2c66affSColin Finck getColor = GetPixel( memhdc, 0, 0 );
112c2c66affSColin Finck ok( getColor == chkColor, "getColor=%08X\n", (UINT)getColor );
113c2c66affSColin Finck
114c2c66affSColin Finck SelectPalette( memhdc, hpalOld, FALSE );
115c2c66affSColin Finck DeleteObject( hpal );
116c2c66affSColin Finck SelectObject( memhdc, hbmpOld );
117c2c66affSColin Finck DeleteObject( hbmp );
118c2c66affSColin Finck DeleteDC( memhdc );
119c2c66affSColin Finck ReleaseDC( NULL, hdc );
120c2c66affSColin Finck }
121c2c66affSColin Finck
test_palette_entries(void)122c2c66affSColin Finck static void test_palette_entries(void)
123c2c66affSColin Finck {
124c2c66affSColin Finck char logpalettebuf[sizeof(LOGPALETTE) + sizeof(logpalettedata)];
125c2c66affSColin Finck PLOGPALETTE logpalette = (PLOGPALETTE)logpalettebuf;
126c2c66affSColin Finck HPALETTE hpal;
127c2c66affSColin Finck UINT res=0;
128c2c66affSColin Finck PALETTEENTRY palEntry = { 0x1, 0x2, 0x3, 0xff };
129c2c66affSColin Finck PALETTEENTRY getEntryResult;
130c2c66affSColin Finck
131c2c66affSColin Finck /* Initialize the logical palette with a few colours */
132c2c66affSColin Finck logpalette->palVersion = 0x300;
133c2c66affSColin Finck logpalette->palNumEntries = 8;
134c2c66affSColin Finck memcpy( logpalette->palPalEntry, logpalettedata, sizeof(logpalettedata) );
135c2c66affSColin Finck hpal = CreatePalette( logpalette );
136c2c66affSColin Finck
137c2c66affSColin Finck /* Set a new entry with peFlags to 0xff */
138c2c66affSColin Finck SetPaletteEntries(hpal, 0, 1, &palEntry);
139c2c66affSColin Finck
140c2c66affSColin Finck /* Retrieve the entry to see if GDI32 performs any filtering on peFlags */
141c2c66affSColin Finck res = GetPaletteEntries(hpal, 0, 1, &getEntryResult);
142c2c66affSColin Finck ok(res == 1, "GetPaletteEntries should have returned 1 but returned %d\n", res);
143c2c66affSColin Finck
144c2c66affSColin Finck ok( palEntry.peFlags == getEntryResult.peFlags, "palEntry.peFlags (%#x) != getEntryResult.peFlags (%#x)\n", palEntry.peFlags, getEntryResult.peFlags );
145c2c66affSColin Finck }
146c2c66affSColin Finck
test_halftone_palette(void)147c2c66affSColin Finck static void test_halftone_palette(void)
148c2c66affSColin Finck {
149c2c66affSColin Finck HDC hdc;
150c2c66affSColin Finck HPALETTE pal;
151c2c66affSColin Finck PALETTEENTRY entries[256];
152c2c66affSColin Finck PALETTEENTRY defpal[20];
153c2c66affSColin Finck int i, count;
154c2c66affSColin Finck
155c2c66affSColin Finck hdc = GetDC(0);
156c2c66affSColin Finck
157c2c66affSColin Finck count = GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, defpal );
158c2c66affSColin Finck ok( count == 20, "wrong size %u\n", count );
159c2c66affSColin Finck
160c2c66affSColin Finck pal = CreateHalftonePalette( hdc );
161c2c66affSColin Finck count = GetPaletteEntries( pal, 0, 256, entries );
162c2c66affSColin Finck ok( count == 256 || broken(count <= 20), /* nt 4 */
163c2c66affSColin Finck "wrong size %u\n", count );
164c2c66affSColin Finck
165c2c66affSColin Finck /* first and last 8 match the default palette */
166c2c66affSColin Finck if (count >= 20)
167c2c66affSColin Finck {
168c2c66affSColin Finck for (i = 0; i < 8; i++)
169c2c66affSColin Finck {
170c2c66affSColin Finck ok( entries[i].peRed == defpal[i].peRed &&
171c2c66affSColin Finck entries[i].peGreen == defpal[i].peGreen &&
172c2c66affSColin Finck entries[i].peBlue == defpal[i].peBlue &&
173c2c66affSColin Finck !entries[i].peFlags,
174c2c66affSColin Finck "%u: wrong color %02x,%02x,%02x,%02x instead of %02x,%02x,%02x\n", i,
175c2c66affSColin Finck entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags,
176c2c66affSColin Finck defpal[i].peRed, defpal[i].peGreen, defpal[i].peBlue );
177c2c66affSColin Finck }
178c2c66affSColin Finck for (i = count - 8; i < count; i++)
179c2c66affSColin Finck {
180c2c66affSColin Finck int idx = i - count + 20;
181c2c66affSColin Finck ok( entries[i].peRed == defpal[idx].peRed &&
182c2c66affSColin Finck entries[i].peGreen == defpal[idx].peGreen &&
183c2c66affSColin Finck entries[i].peBlue == defpal[idx].peBlue &&
184c2c66affSColin Finck !entries[i].peFlags,
185c2c66affSColin Finck "%u: wrong color %02x,%02x,%02x,%02x instead of %02x,%02x,%02x\n", i,
186c2c66affSColin Finck entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags,
187c2c66affSColin Finck defpal[idx].peRed, defpal[idx].peGreen, defpal[idx].peBlue );
188c2c66affSColin Finck }
189c2c66affSColin Finck }
190c2c66affSColin Finck DeleteObject( pal );
191c2c66affSColin Finck ReleaseDC( 0, hdc );
192c2c66affSColin Finck }
193c2c66affSColin Finck
check_system_palette_entries(HDC hdc)194c2c66affSColin Finck static void check_system_palette_entries(HDC hdc)
195c2c66affSColin Finck {
196c2c66affSColin Finck PALETTEENTRY entries[256];
197c2c66affSColin Finck PALETTEENTRY defpal[20];
198c2c66affSColin Finck int i, count;
199c2c66affSColin Finck
200c2c66affSColin Finck memset( defpal, 0xaa, sizeof(defpal) );
201c2c66affSColin Finck count = GetPaletteEntries( GetStockObject(DEFAULT_PALETTE), 0, 20, defpal );
202c2c66affSColin Finck ok( count == 20, "wrong size %u\n", count );
203c2c66affSColin Finck
204c2c66affSColin Finck memset( entries, 0x55, sizeof(entries) );
205c2c66affSColin Finck count = GetSystemPaletteEntries( hdc, 0, 256, entries );
206c2c66affSColin Finck ok( count == 0, "wrong size %u\n", count);
207c2c66affSColin Finck for (i = 0; i < 10; i++)
208c2c66affSColin Finck {
209c2c66affSColin Finck ok( entries[i].peRed == defpal[i].peRed &&
210c2c66affSColin Finck entries[i].peGreen == defpal[i].peGreen &&
211c2c66affSColin Finck entries[i].peBlue == defpal[i].peBlue &&
212c2c66affSColin Finck !entries[i].peFlags,
213c2c66affSColin Finck "%u: wrong color %02x,%02x,%02x,%02x instead of %02x,%02x,%02x\n", i,
214c2c66affSColin Finck entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags,
215c2c66affSColin Finck defpal[i].peRed, defpal[i].peGreen, defpal[i].peBlue );
216c2c66affSColin Finck }
217c2c66affSColin Finck for (i = 10; i < 246; ++i)
218c2c66affSColin Finck {
219c2c66affSColin Finck ok( !entries[i].peRed &&
220c2c66affSColin Finck !entries[i].peGreen &&
221c2c66affSColin Finck !entries[i].peBlue &&
222c2c66affSColin Finck !entries[i].peFlags,
223c2c66affSColin Finck "%u: wrong color %02x,%02x,%02x,%02x instead of 0,0,0\n", i,
224c2c66affSColin Finck entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags);
225c2c66affSColin Finck }
226c2c66affSColin Finck for (i = 246; i < 256; i++)
227c2c66affSColin Finck {
228c2c66affSColin Finck int idx = i - 246 + 10;
229c2c66affSColin Finck ok( entries[i].peRed == defpal[idx].peRed &&
230c2c66affSColin Finck entries[i].peGreen == defpal[idx].peGreen &&
231c2c66affSColin Finck entries[i].peBlue == defpal[idx].peBlue &&
232c2c66affSColin Finck !entries[i].peFlags,
233c2c66affSColin Finck "%u: wrong color %02x,%02x,%02x,%02x instead of %02x,%02x,%02x\n", i,
234c2c66affSColin Finck entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags,
235c2c66affSColin Finck defpal[idx].peRed, defpal[idx].peGreen, defpal[idx].peBlue );
236c2c66affSColin Finck }
237c2c66affSColin Finck
238c2c66affSColin Finck memset( entries, 0x55, sizeof(entries) );
239c2c66affSColin Finck count = GetSystemPaletteEntries( hdc, 0, 10, entries );
240c2c66affSColin Finck ok( count == 0, "wrong size %u\n", count);
241c2c66affSColin Finck for (i = 0; i < 10; i++)
242c2c66affSColin Finck {
243c2c66affSColin Finck ok( entries[i].peRed == defpal[i].peRed &&
244c2c66affSColin Finck entries[i].peGreen == defpal[i].peGreen &&
245c2c66affSColin Finck entries[i].peBlue == defpal[i].peBlue &&
246c2c66affSColin Finck !entries[i].peFlags,
247c2c66affSColin Finck "%u: wrong color %02x,%02x,%02x,%02x instead of %02x,%02x,%02x\n", i,
248c2c66affSColin Finck entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags,
249c2c66affSColin Finck defpal[i].peRed, defpal[i].peGreen, defpal[i].peBlue );
250c2c66affSColin Finck }
251c2c66affSColin Finck
252c2c66affSColin Finck memset( entries, 0x55, sizeof(entries) );
253c2c66affSColin Finck count = GetSystemPaletteEntries( hdc, 10, 246, entries );
254c2c66affSColin Finck ok( count == 0, "wrong size %u\n", count);
255c2c66affSColin Finck for (i = 0; i < 236; ++i)
256c2c66affSColin Finck {
257c2c66affSColin Finck ok( !entries[i].peRed &&
258c2c66affSColin Finck !entries[i].peGreen &&
259c2c66affSColin Finck !entries[i].peBlue &&
260c2c66affSColin Finck !entries[i].peFlags,
261c2c66affSColin Finck "%u: wrong color %02x,%02x,%02x,%02x instead of 0,0,0\n", i,
262c2c66affSColin Finck entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags);
263c2c66affSColin Finck }
264c2c66affSColin Finck for (i = 236; i < 246; i++)
265c2c66affSColin Finck {
266c2c66affSColin Finck int idx = i - 236 + 10;
267c2c66affSColin Finck ok( entries[i].peRed == defpal[idx].peRed &&
268c2c66affSColin Finck entries[i].peGreen == defpal[idx].peGreen &&
269c2c66affSColin Finck entries[i].peBlue == defpal[idx].peBlue &&
270c2c66affSColin Finck !entries[i].peFlags,
271c2c66affSColin Finck "%u: wrong color %02x,%02x,%02x,%02x instead of %02x,%02x,%02x\n", i,
272c2c66affSColin Finck entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags,
273c2c66affSColin Finck defpal[idx].peRed, defpal[idx].peGreen, defpal[idx].peBlue );
274c2c66affSColin Finck }
275c2c66affSColin Finck
276c2c66affSColin Finck memset( entries, 0x55, sizeof(entries) );
277c2c66affSColin Finck count = GetSystemPaletteEntries( hdc, 246, 10, entries );
278c2c66affSColin Finck ok( count == 0, "wrong size %u\n", count);
279c2c66affSColin Finck for (i = 0; i < 10; i++)
280c2c66affSColin Finck {
281c2c66affSColin Finck int idx = i + 10;
282c2c66affSColin Finck ok( entries[i].peRed == defpal[idx].peRed &&
283c2c66affSColin Finck entries[i].peGreen == defpal[idx].peGreen &&
284c2c66affSColin Finck entries[i].peBlue == defpal[idx].peBlue &&
285c2c66affSColin Finck !entries[i].peFlags,
286c2c66affSColin Finck "%u: wrong color %02x,%02x,%02x,%02x instead of %02x,%02x,%02x\n", i,
287c2c66affSColin Finck entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags,
288c2c66affSColin Finck defpal[idx].peRed, defpal[idx].peGreen, defpal[idx].peBlue );
289c2c66affSColin Finck }
290c2c66affSColin Finck }
291c2c66affSColin Finck
test_system_palette_entries(void)292c2c66affSColin Finck static void test_system_palette_entries(void)
293c2c66affSColin Finck {
294c2c66affSColin Finck HDC hdc;
295c2c66affSColin Finck HDC metafile_dc;
296c2c66affSColin Finck HMETAFILE metafile;
297c2c66affSColin Finck
298c2c66affSColin Finck hdc = GetDC(0);
299c2c66affSColin Finck
300c2c66affSColin Finck if (!(GetDeviceCaps( hdc, RASTERCAPS ) & RC_PALETTE))
301c2c66affSColin Finck {
302c2c66affSColin Finck check_system_palette_entries(hdc);
303c2c66affSColin Finck }
304c2c66affSColin Finck else
305c2c66affSColin Finck {
306c2c66affSColin Finck skip( "device is palette-based, skipping test\n" );
307c2c66affSColin Finck }
308c2c66affSColin Finck
309c2c66affSColin Finck ReleaseDC( 0, hdc );
310c2c66affSColin Finck
311c2c66affSColin Finck metafile_dc = CreateMetaFileA(NULL);
312c2c66affSColin Finck
313c2c66affSColin Finck check_system_palette_entries(metafile_dc);
314c2c66affSColin Finck
315c2c66affSColin Finck metafile = CloseMetaFile(metafile_dc);
316c2c66affSColin Finck DeleteMetaFile(metafile);
317c2c66affSColin Finck }
318c2c66affSColin Finck
START_TEST(palette)319c2c66affSColin Finck START_TEST(palette)
320c2c66affSColin Finck {
321c2c66affSColin Finck test_DIB_PAL_COLORS();
322c2c66affSColin Finck test_palette_entries();
323c2c66affSColin Finck test_halftone_palette();
324c2c66affSColin Finck test_system_palette_entries();
325c2c66affSColin Finck }
326