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