quartz: Use proper alloc/free functions for COM objects.
[wine] / dlls / gdi32 / tests / bitmap.c
1 /*
2  * Unit test suite for bitmaps
3  *
4  * Copyright 2004 Huw Davies
5  * Copyright 2006 Dmitry Timoshkov
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include <stdarg.h>
23 #include <assert.h>
24 #include <string.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "winuser.h"
30 #include "mmsystem.h"
31
32 #include "wine/test.h"
33
34 static BOOL is_win9x;
35
36 static INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
37 {
38     switch(bpp)
39     {
40     case 1:
41         return 2 * ((bmWidth+15) >> 4);
42
43     case 24:
44         bmWidth *= 3; /* fall through */
45     case 8:
46         return bmWidth + (bmWidth & 1);
47
48     case 32:
49         return bmWidth * 4;
50
51     case 16:
52     case 15:
53         return bmWidth * 2;
54
55     case 4:
56         return 2 * ((bmWidth+3) >> 2);
57
58     default:
59         trace("Unknown depth %d, please report.\n", bpp );
60         assert(0);
61     }
62     return -1;
63 }
64
65 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
66 {
67     BITMAP bm;
68     INT ret, width_bytes;
69     char buf[512], buf_cmp[512];
70
71     ret = GetObject(hbm, sizeof(bm), &bm);
72     ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
73
74     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
75     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
76     ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
77     width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
78     ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
79     ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
80     ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
81     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
82
83     assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
84     assert(sizeof(buf) == sizeof(buf_cmp));
85
86     ret = GetBitmapBits(hbm, 0, NULL);
87     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
88
89     memset(buf_cmp, 0xAA, sizeof(buf_cmp));
90     memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
91
92     memset(buf, 0xAA, sizeof(buf));
93     ret = GetBitmapBits(hbm, sizeof(buf), buf);
94     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
95     ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
96
97     /* test various buffer sizes for GetObject */
98     ret = GetObject(hbm, 0, NULL);
99     ok(ret == sizeof(bm), "wrong size %d\n", ret);
100
101     ret = GetObject(hbm, sizeof(bm) * 2, &bm);
102     ok(ret == sizeof(bm), "wrong size %d\n", ret);
103
104     ret = GetObject(hbm, sizeof(bm) / 2, &bm);
105     ok(ret == 0, "%d != 0\n", ret);
106
107     ret = GetObject(hbm, 0, &bm);
108     ok(ret == 0, "%d != 0\n", ret);
109
110     ret = GetObject(hbm, 1, &bm);
111     ok(ret == 0, "%d != 0\n", ret);
112 }
113
114 static void test_createdibitmap(void)
115 {
116     HDC hdc, hdcmem;
117     BITMAPINFOHEADER bmih;
118     HBITMAP hbm, hbm_colour, hbm_old;
119     INT screen_depth;
120
121     hdc = GetDC(0);
122     screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
123     memset(&bmih, 0, sizeof(bmih));
124     bmih.biSize = sizeof(bmih);
125     bmih.biWidth = 10;
126     bmih.biHeight = 10;
127     bmih.biPlanes = 1;
128     bmih.biBitCount = 32;
129     bmih.biCompression = BI_RGB;
130  
131     /* First create an un-initialised bitmap.  The depth of the bitmap
132        should match that of the hdc and not that supplied in bmih.
133     */
134
135     /* First try 32 bits */
136     hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
137     ok(hbm != NULL, "CreateDIBitmap failed\n");
138     test_bitmap_info(hbm, screen_depth, &bmih);
139     DeleteObject(hbm);
140     
141     /* Then 16 */
142     bmih.biBitCount = 16;
143     hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
144     ok(hbm != NULL, "CreateDIBitmap failed\n");
145     test_bitmap_info(hbm, screen_depth, &bmih);
146     DeleteObject(hbm);
147
148     /* Then 1 */
149     bmih.biBitCount = 1;
150     hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
151     ok(hbm != NULL, "CreateDIBitmap failed\n");
152     test_bitmap_info(hbm, screen_depth, &bmih);
153     DeleteObject(hbm);
154
155     /* Now with a monochrome dc we expect a monochrome bitmap */
156     hdcmem = CreateCompatibleDC(hdc);
157
158     /* First try 32 bits */
159     bmih.biBitCount = 32;
160     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
161     ok(hbm != NULL, "CreateDIBitmap failed\n");
162     test_bitmap_info(hbm, 1, &bmih);
163     DeleteObject(hbm);
164     
165     /* Then 16 */
166     bmih.biBitCount = 16;
167     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
168     ok(hbm != NULL, "CreateDIBitmap failed\n");
169     test_bitmap_info(hbm, 1, &bmih);
170     DeleteObject(hbm);
171     
172     /* Then 1 */
173     bmih.biBitCount = 1;
174     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
175     ok(hbm != NULL, "CreateDIBitmap failed\n");
176     test_bitmap_info(hbm, 1, &bmih);
177     DeleteObject(hbm);
178
179     /* Now select a polychrome bitmap into the dc and we expect
180        screen_depth bitmaps again */
181     hbm_colour = CreateCompatibleBitmap(hdc, 1, 1);
182     hbm_old = SelectObject(hdcmem, hbm_colour);
183
184     /* First try 32 bits */
185     bmih.biBitCount = 32;
186     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
187     ok(hbm != NULL, "CreateDIBitmap failed\n");
188     test_bitmap_info(hbm, screen_depth, &bmih);
189     DeleteObject(hbm);
190     
191     /* Then 16 */
192     bmih.biBitCount = 16;
193     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
194     ok(hbm != NULL, "CreateDIBitmap failed\n");
195     test_bitmap_info(hbm, screen_depth, &bmih);
196     DeleteObject(hbm);
197     
198     /* Then 1 */
199     bmih.biBitCount = 1;
200     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
201     ok(hbm != NULL, "CreateDIBitmap failed\n");
202     test_bitmap_info(hbm, screen_depth, &bmih);
203     DeleteObject(hbm);
204
205     SelectObject(hdcmem, hbm_old);
206     DeleteObject(hbm_colour);
207     DeleteDC(hdcmem);
208
209     /* If hdc == 0 then we get a 1 bpp bitmap */
210     if (!is_win9x) {
211         bmih.biBitCount = 32;
212         hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
213         ok(hbm != NULL, "CreateDIBitmap failed\n");
214         test_bitmap_info(hbm, 1, &bmih);
215         DeleteObject(hbm);
216     }
217     
218     ReleaseDC(0, hdc);
219 }
220
221 static INT DIB_GetWidthBytes( int width, int bpp )
222 {
223     int words;
224
225     switch (bpp)
226     {
227         case 1:  words = (width + 31) / 32; break;
228         case 4:  words = (width + 7) / 8; break;
229         case 8:  words = (width + 3) / 4; break;
230         case 15:
231         case 16: words = (width + 1) / 2; break;
232         case 24: words = (width * 3 + 3)/4; break;
233         case 32: words = width; break;
234
235         default:
236             words=0;
237             trace("Unknown depth %d, please report.\n", bpp );
238             assert(0);
239             break;
240     }
241     return 4 * words;
242 }
243
244 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
245 {
246     BITMAP bm;
247     DIBSECTION ds;
248     INT ret, width_bytes;
249     BYTE *buf;
250
251     ret = GetObject(hbm, sizeof(bm), &bm);
252     ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
253
254     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
255     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
256     ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
257     width_bytes = DIB_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
258     ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
259     ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
260     ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
261     ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
262
263     buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
264
265     width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
266
267     /* GetBitmapBits returns not 32-bit aligned data */
268     ret = GetBitmapBits(hbm, 0, NULL);
269     ok(ret == width_bytes * bm.bmHeight, "%d != %d\n", ret, width_bytes * bm.bmHeight);
270
271     memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
272     ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
273     ok(ret == width_bytes * bm.bmHeight, "%d != %d\n", ret, width_bytes * bm.bmHeight);
274
275     HeapFree(GetProcessHeap(), 0, buf);
276
277     /* test various buffer sizes for GetObject */
278     memset(&ds, 0xAA, sizeof(ds));
279     ret = GetObject(hbm, sizeof(bm) * 2, &bm);
280     ok(ret == sizeof(bm), "wrong size %d\n", ret);
281     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
282     ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
283     ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
284
285     ret = GetObject(hbm, sizeof(bm) / 2, &bm);
286     ok(ret == 0, "%d != 0\n", ret);
287
288     ret = GetObject(hbm, 0, &bm);
289     ok(ret == 0, "%d != 0\n", ret);
290
291     ret = GetObject(hbm, 1, &bm);
292     ok(ret == 0, "%d != 0\n", ret);
293
294     /* test various buffer sizes for GetObject */
295     ret = GetObject(hbm, 0, NULL);
296     ok(ret == sizeof(bm), "wrong size %d\n", ret);
297
298     memset(&ds, 0xAA, sizeof(ds));
299     ret = GetObject(hbm, sizeof(ds) * 2, &ds);
300     ok(ret == sizeof(ds), "wrong size %d\n", ret);
301
302     ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
303     ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
304        ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
305     ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
306     ds.dsBmih.biSizeImage = 0;
307
308     ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
309     ok(ds.dsBmih.biWidth == bmih->biWidth, "%u != %u\n", ds.dsBmih.biWidth, bmih->biWidth);
310     ok(ds.dsBmih.biHeight == bmih->biHeight, "%u != %u\n", ds.dsBmih.biHeight, bmih->biHeight);
311     ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
312     ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
313     ok(ds.dsBmih.biCompression == bmih->biCompression, "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
314     ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
315     ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%u != %u\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
316     ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%u != %u\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
317
318     memset(&ds, 0xAA, sizeof(ds));
319     ret = GetObject(hbm, sizeof(ds) - 4, &ds);
320     ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
321     ok(ds.dsBm.bmWidth == bmih->biWidth, "%u != %u\n", ds.dsBmih.biWidth, bmih->biWidth);
322     ok(ds.dsBm.bmHeight == bmih->biHeight, "%u != %u\n", ds.dsBmih.biHeight, bmih->biHeight);
323     ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
324
325     ret = GetObject(hbm, 0, &ds);
326     ok(ret == 0, "%d != 0\n", ret);
327
328     ret = GetObject(hbm, 1, &ds);
329     ok(ret == 0, "%d != 0\n", ret);
330 }
331
332 #define test_color_todo(got, exp, txt, todo) \
333     if (!todo && got != exp && screen_depth < 24) { \
334       todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
335                    screen_depth, (UINT)got, (UINT)exp); \
336       return; \
337     } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
338     else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \
339
340 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
341 { \
342     COLORREF c; \
343     c = SetPixel(hdc, 0, 0, color); \
344     if (!is_win9x) { test_color_todo(c, exp, SetPixel, todo_setp); } \
345     c = GetPixel(hdc, 0, 0); \
346     test_color_todo(c, exp, GetPixel, todo_getp); \
347 }
348
349 static void test_dibsections(void)
350 {
351     HDC hdc, hdcmem, hdcmem2;
352     HBITMAP hdib, oldbm, hdib2, oldbm2;
353     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
354     char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
355     BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
356     BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
357     HBITMAP hcoredib;
358     char coreBits[256];
359     BYTE *bits;
360     RGBQUAD rgb[256];
361     int ret;
362     char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
363     LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
364     WORD *index;
365     DWORD *bits32;
366     HPALETTE hpal, oldpal;
367     DIBSECTION dibsec;
368     COLORREF c0, c1;
369     int i;
370     int screen_depth;
371     MEMORY_BASIC_INFORMATION info;
372
373     hdc = GetDC(0);
374     screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
375
376     memset(pbmi, 0, sizeof(bmibuf));
377     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
378     pbmi->bmiHeader.biHeight = 100;
379     pbmi->bmiHeader.biWidth = 512;
380     pbmi->bmiHeader.biBitCount = 24;
381     pbmi->bmiHeader.biPlanes = 1;
382     pbmi->bmiHeader.biCompression = BI_RGB;
383
384     SetLastError(0xdeadbeef);
385     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
386     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
387     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
388     ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
389
390     /* test the DIB memory */
391     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
392         "VirtualQuery failed\n");
393     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
394     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
395     ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
396     ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
397     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
398     ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
399     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
400
401     test_dib_info(hdib, bits, &pbmi->bmiHeader);
402     DeleteObject(hdib);
403
404     pbmi->bmiHeader.biBitCount = 8;
405     pbmi->bmiHeader.biCompression = BI_RLE8;
406     SetLastError(0xdeadbeef);
407     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
408     ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
409     ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
410
411     pbmi->bmiHeader.biBitCount = 16;
412     pbmi->bmiHeader.biCompression = BI_BITFIELDS;
413     ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
414     ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
415     ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
416     SetLastError(0xdeadbeef);
417     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
418     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
419
420     /* test the DIB memory */
421     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
422         "VirtualQuery failed\n");
423     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
424     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
425     ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
426     ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
427     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
428     ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
429     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
430
431     test_dib_info(hdib, bits, &pbmi->bmiHeader);
432     DeleteObject(hdib);
433
434     memset(pbmi, 0, sizeof(bmibuf));
435     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
436     pbmi->bmiHeader.biHeight = 16;
437     pbmi->bmiHeader.biWidth = 16;
438     pbmi->bmiHeader.biBitCount = 1;
439     pbmi->bmiHeader.biPlanes = 1;
440     pbmi->bmiHeader.biCompression = BI_RGB;
441     pbmi->bmiColors[0].rgbRed = 0xff;
442     pbmi->bmiColors[0].rgbGreen = 0;
443     pbmi->bmiColors[0].rgbBlue = 0;
444     pbmi->bmiColors[1].rgbRed = 0;
445     pbmi->bmiColors[1].rgbGreen = 0;
446     pbmi->bmiColors[1].rgbBlue = 0xff;
447
448     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
449     ok(hdib != NULL, "CreateDIBSection failed\n");
450     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
451     ok(dibsec.dsBmih.biClrUsed == 2,
452         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
453
454     /* Test if the old BITMAPCOREINFO structure is supported */    
455         
456     pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
457     pbci->bmciHeader.bcBitCount = 0;
458
459     if (!is_win9x) {
460         ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
461         ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
462         ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
463             && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
464         "GetDIBits did't fill in the BITMAPCOREHEADER structure properly\n");
465
466         ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
467         ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
468         ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
469             (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
470             (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
471             "The color table has not been translated to the old BITMAPCOREINFO format\n");
472
473         hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
474         ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
475
476         ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
477         ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
478         ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
479         ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
480             (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
481             (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
482             "The color table has not been translated to the old BITMAPCOREINFO format\n");
483
484         DeleteObject(hcoredib);
485     }
486
487     hdcmem = CreateCompatibleDC(hdc);
488     oldbm = SelectObject(hdcmem, hdib);
489
490     ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
491     ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
492     ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
493        "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
494        rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
495        rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
496
497     c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
498     c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
499
500     test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
501     test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
502     test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
503     test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
504     test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
505     test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
506     test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
507         pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
508     test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
509         pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
510     test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
511     test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
512     test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
513
514     SelectObject(hdcmem, oldbm);
515     DeleteObject(hdib);
516
517     pbmi->bmiColors[0].rgbRed = 0xff;
518     pbmi->bmiColors[0].rgbGreen = 0xff;
519     pbmi->bmiColors[0].rgbBlue = 0xff;
520     pbmi->bmiColors[1].rgbRed = 0;
521     pbmi->bmiColors[1].rgbGreen = 0;
522     pbmi->bmiColors[1].rgbBlue = 0;
523
524     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
525     ok(hdib != NULL, "CreateDIBSection failed\n");
526
527     test_dib_info(hdib, bits, &pbmi->bmiHeader);
528
529     oldbm = SelectObject(hdcmem, hdib);
530
531     ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
532     ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
533     ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
534        "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
535        rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
536        rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
537
538     SelectObject(hdcmem, oldbm);
539     test_dib_info(hdib, bits, &pbmi->bmiHeader);
540     DeleteObject(hdib);
541
542     pbmi->bmiHeader.biBitCount = 4;
543     for (i = 0; i < 16; i++) {
544         pbmi->bmiColors[i].rgbRed = i;
545         pbmi->bmiColors[i].rgbGreen = 16-i;
546         pbmi->bmiColors[i].rgbBlue = 0;
547     }
548     hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
549     ok(hdib != NULL, "CreateDIBSection failed\n");
550     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
551     ok(dibsec.dsBmih.biClrUsed == 16,
552        "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
553     test_dib_info(hdib, bits, &pbmi->bmiHeader);
554     DeleteObject(hdib);
555
556     pbmi->bmiHeader.biBitCount = 8;
557
558     for (i = 0; i < 128; i++) {
559         pbmi->bmiColors[i].rgbRed = 255 - i * 2;
560         pbmi->bmiColors[i].rgbGreen = i * 2;
561         pbmi->bmiColors[i].rgbBlue = 0;
562         pbmi->bmiColors[255 - i].rgbRed = 0;
563         pbmi->bmiColors[255 - i].rgbGreen = i * 2;
564         pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
565     }
566     hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
567     ok(hdib != NULL, "CreateDIBSection failed\n");
568     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
569     ok(dibsec.dsBmih.biClrUsed == 256,
570         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
571
572     oldbm = SelectObject(hdcmem, hdib);
573
574     for (i = 0; i < 256; i++) {
575         test_color(hdcmem, DIBINDEX(i), 
576             RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
577         test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 
578             RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
579     }
580
581     SelectObject(hdcmem, oldbm);
582     test_dib_info(hdib, bits, &pbmi->bmiHeader);
583     DeleteObject(hdib);
584
585     pbmi->bmiHeader.biBitCount = 1;
586
587     /* Now create a palette and a palette indexed dib section */
588     memset(plogpal, 0, sizeof(logpalbuf));
589     plogpal->palVersion = 0x300;
590     plogpal->palNumEntries = 2;
591     plogpal->palPalEntry[0].peRed = 0xff;
592     plogpal->palPalEntry[0].peBlue = 0xff;
593     plogpal->palPalEntry[1].peGreen = 0xff;
594
595     index = (WORD*)pbmi->bmiColors;
596     *index++ = 0;
597     *index = 1;
598     hpal = CreatePalette(plogpal);
599     ok(hpal != NULL, "CreatePalette failed\n");
600     oldpal = SelectPalette(hdc, hpal, TRUE);
601     hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
602     ok(hdib != NULL, "CreateDIBSection failed\n");
603     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
604     ok(dibsec.dsBmih.biClrUsed == 2,
605         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
606
607     /* The colour table has already been grabbed from the dc, so we select back the
608        old palette */
609
610     SelectPalette(hdc, oldpal, TRUE);
611     oldbm = SelectObject(hdcmem, hdib);
612     oldpal = SelectPalette(hdcmem, hpal, TRUE);
613
614     ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
615     ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
616     ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
617        rgb[1].rgbRed == 0    && rgb[1].rgbBlue == 0    && rgb[1].rgbGreen == 0xff,
618        "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
619        rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
620        rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
621
622     c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
623     c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
624
625     test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
626     test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
627     test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
628     test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
629     test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
630     test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
631     test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
632         plogpal->palPalEntry[0].peBlue), c0, 1, 1);
633     test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
634         plogpal->palPalEntry[1].peBlue), c1, 1, 1);
635     test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
636     test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
637     test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
638     test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
639     test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
640     test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
641
642     /* Bottom and 2nd row from top green, everything else magenta */
643     bits[0] = bits[1] = 0xff;
644     bits[13 * 4] = bits[13*4 + 1] = 0xff;
645
646     test_dib_info(hdib, bits, &pbmi->bmiHeader);
647
648     pbmi->bmiHeader.biBitCount = 32;
649
650     hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
651     ok(hdib2 != NULL, "CreateDIBSection failed\n");
652     hdcmem2 = CreateCompatibleDC(hdc);
653     oldbm2 = SelectObject(hdcmem2, hdib2);
654
655     BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
656
657     ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
658     ok(bits32[17] == 0xff00ff, "bottom but one, left pixel is %08x\n", bits32[17]);
659
660     SelectObject(hdcmem2, oldbm2);
661     test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
662     DeleteObject(hdib2);
663
664     SelectObject(hdcmem, oldbm);
665     SelectObject(hdcmem, oldpal);
666     DeleteObject(hdib);
667     DeleteObject(hpal);
668
669
670     pbmi->bmiHeader.biBitCount = 8;
671
672     memset(plogpal, 0, sizeof(logpalbuf));
673     plogpal->palVersion = 0x300;
674     plogpal->palNumEntries = 256;
675
676     for (i = 0; i < 128; i++) {
677         plogpal->palPalEntry[i].peRed = 255 - i * 2;
678         plogpal->palPalEntry[i].peBlue = i * 2;
679         plogpal->palPalEntry[i].peGreen = 0;
680         plogpal->palPalEntry[255 - i].peRed = 0;
681         plogpal->palPalEntry[255 - i].peGreen = i * 2;
682         plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
683     }
684
685     index = (WORD*)pbmi->bmiColors;
686     for (i = 0; i < 256; i++) {
687         *index++ = i;
688     }
689
690     hpal = CreatePalette(plogpal);
691     ok(hpal != NULL, "CreatePalette failed\n");
692     oldpal = SelectPalette(hdc, hpal, TRUE);
693     hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
694     ok(hdib != NULL, "CreateDIBSection failed\n");
695     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
696     ok(dibsec.dsBmih.biClrUsed == 256,
697         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
698
699     test_dib_info(hdib, bits, &pbmi->bmiHeader);
700
701     SelectPalette(hdc, oldpal, TRUE);
702     oldbm = SelectObject(hdcmem, hdib);
703     oldpal = SelectPalette(hdcmem, hpal, TRUE);
704
705     ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
706     ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
707     for (i = 0; i < 256; i++) {
708         ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed && 
709             rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue && 
710             rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen, 
711             "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
712             i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
713     }
714
715     for (i = 0; i < 256; i++) {
716         test_color(hdcmem, DIBINDEX(i), 
717             RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
718         test_color(hdcmem, PALETTEINDEX(i), 
719             RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
720         test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 
721             RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
722     }
723
724     SelectPalette(hdcmem, oldpal, TRUE);
725     SelectObject(hdcmem, oldbm);
726     DeleteObject(hdib);
727     DeleteObject(hpal);
728
729
730     DeleteDC(hdcmem);
731     ReleaseDC(0, hdc);
732 }
733
734 static void test_mono_dibsection(void)
735 {
736     HDC hdc, memdc;
737     HBITMAP old_bm, mono_ds;
738     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
739     BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
740     BYTE bits[10 * 4];
741     BYTE *ds_bits;
742     int num;
743
744     hdc = GetDC(0);
745
746     memdc = CreateCompatibleDC(hdc);
747
748     memset(pbmi, 0, sizeof(bmibuf));
749     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
750     pbmi->bmiHeader.biHeight = 10;
751     pbmi->bmiHeader.biWidth = 10;
752     pbmi->bmiHeader.biBitCount = 1;
753     pbmi->bmiHeader.biPlanes = 1;
754     pbmi->bmiHeader.biCompression = BI_RGB;
755     pbmi->bmiColors[0].rgbRed = 0xff;
756     pbmi->bmiColors[0].rgbGreen = 0xff;
757     pbmi->bmiColors[0].rgbBlue = 0xff;
758     pbmi->bmiColors[1].rgbRed = 0x0;
759     pbmi->bmiColors[1].rgbGreen = 0x0;
760     pbmi->bmiColors[1].rgbBlue = 0x0;
761
762     /*
763      * First dib section is 'inverted' ie color[0] is white, color[1] is black
764      */
765
766     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
767     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
768     old_bm = SelectObject(memdc, mono_ds);
769
770     /* black border, white interior */
771     Rectangle(memdc, 0, 0, 10, 10);
772     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
773     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
774
775     /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
776
777     memset(bits, 0, sizeof(bits));
778     bits[0] = 0xaa;
779
780     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
781     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
782
783     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
784
785     pbmi->bmiColors[0].rgbRed = 0x0;
786     pbmi->bmiColors[0].rgbGreen = 0x0;
787     pbmi->bmiColors[0].rgbBlue = 0x0;
788     pbmi->bmiColors[1].rgbRed = 0xff;
789     pbmi->bmiColors[1].rgbGreen = 0xff;
790     pbmi->bmiColors[1].rgbBlue = 0xff;
791
792     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
793     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
794
795     SelectObject(memdc, old_bm);
796     DeleteObject(mono_ds);
797
798     /*
799      * Next dib section is 'normal' ie color[0] is black, color[1] is white
800      */
801
802     pbmi->bmiColors[0].rgbRed = 0x0;
803     pbmi->bmiColors[0].rgbGreen = 0x0;
804     pbmi->bmiColors[0].rgbBlue = 0x0;
805     pbmi->bmiColors[1].rgbRed = 0xff;
806     pbmi->bmiColors[1].rgbGreen = 0xff;
807     pbmi->bmiColors[1].rgbBlue = 0xff;
808
809     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
810     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
811     old_bm = SelectObject(memdc, mono_ds);
812
813     /* black border, white interior */
814     Rectangle(memdc, 0, 0, 10, 10);
815     ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
816     ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
817
818     /* SetDIBitsToDevice with a normal bmi -> normal dib section */
819
820     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
821     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
822
823     /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
824
825     pbmi->bmiColors[0].rgbRed = 0xff;
826     pbmi->bmiColors[0].rgbGreen = 0xff;
827     pbmi->bmiColors[0].rgbBlue = 0xff;
828     pbmi->bmiColors[1].rgbRed = 0x0;
829     pbmi->bmiColors[1].rgbGreen = 0x0;
830     pbmi->bmiColors[1].rgbBlue = 0x0;
831
832     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
833     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
834
835     /*
836      * Take that 'normal' dibsection and change its colour table to an 'inverted' one
837      */
838
839     pbmi->bmiColors[0].rgbRed = 0xff;
840     pbmi->bmiColors[0].rgbGreen = 0xff;
841     pbmi->bmiColors[0].rgbBlue = 0xff;
842     pbmi->bmiColors[1].rgbRed = 0x0;
843     pbmi->bmiColors[1].rgbGreen = 0x0;
844     pbmi->bmiColors[1].rgbBlue = 0x0;
845     num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
846     ok(num == 2, "num = %d\n", num);
847
848     /* black border, white interior */
849     Rectangle(memdc, 0, 0, 10, 10);
850 todo_wine {
851     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
852     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
853  }
854     /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
855
856     memset(bits, 0, sizeof(bits));
857     bits[0] = 0xaa;
858
859     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
860     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
861
862     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
863
864     pbmi->bmiColors[0].rgbRed = 0x0;
865     pbmi->bmiColors[0].rgbGreen = 0x0;
866     pbmi->bmiColors[0].rgbBlue = 0x0;
867     pbmi->bmiColors[1].rgbRed = 0xff;
868     pbmi->bmiColors[1].rgbGreen = 0xff;
869     pbmi->bmiColors[1].rgbBlue = 0xff;
870
871     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
872     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
873
874     SelectObject(memdc, old_bm);
875     DeleteObject(mono_ds);
876
877     /*
878      * Now a dib section with a strange colour map just for fun.  This behaves just like an inverted one.
879      */
880  
881     pbmi->bmiColors[0].rgbRed = 0xff;
882     pbmi->bmiColors[0].rgbGreen = 0x0;
883     pbmi->bmiColors[0].rgbBlue = 0x0;
884     pbmi->bmiColors[1].rgbRed = 0xfe;
885     pbmi->bmiColors[1].rgbGreen = 0x0;
886     pbmi->bmiColors[1].rgbBlue = 0x0;
887
888     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
889     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
890     old_bm = SelectObject(memdc, mono_ds);
891
892     /* black border, white interior */
893     Rectangle(memdc, 0, 0, 10, 10);
894     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
895     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
896
897     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
898
899     pbmi->bmiColors[0].rgbRed = 0x0;
900     pbmi->bmiColors[0].rgbGreen = 0x0;
901     pbmi->bmiColors[0].rgbBlue = 0x0;
902     pbmi->bmiColors[1].rgbRed = 0xff;
903     pbmi->bmiColors[1].rgbGreen = 0xff;
904     pbmi->bmiColors[1].rgbBlue = 0xff;
905
906     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
907     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
908
909     /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
910
911     pbmi->bmiColors[0].rgbRed = 0xff;
912     pbmi->bmiColors[0].rgbGreen = 0xff;
913     pbmi->bmiColors[0].rgbBlue = 0xff;
914     pbmi->bmiColors[1].rgbRed = 0x0;
915     pbmi->bmiColors[1].rgbGreen = 0x0;
916     pbmi->bmiColors[1].rgbBlue = 0x0;
917
918     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
919     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
920
921     SelectObject(memdc, old_bm);
922     DeleteObject(mono_ds);
923
924     DeleteDC(memdc);
925     ReleaseDC(0, hdc);
926 }
927
928 static void test_bitmap(void)
929 {
930     char buf[256], buf_cmp[256];
931     HBITMAP hbmp, hbmp_old;
932     HDC hdc;
933     BITMAP bm;
934     INT ret;
935
936     hdc = CreateCompatibleDC(0);
937     assert(hdc != 0);
938
939     hbmp = CreateBitmap(15, 15, 1, 1, NULL);
940     assert(hbmp != NULL);
941
942     ret = GetObject(hbmp, sizeof(bm), &bm);
943     ok(ret == sizeof(bm), "wrong size %d\n", ret);
944
945     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
946     ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
947     ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
948     ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
949     ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
950     ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
951     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
952
953     assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
954     assert(sizeof(buf) == sizeof(buf_cmp));
955
956     ret = GetBitmapBits(hbmp, 0, NULL);
957     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
958
959     memset(buf_cmp, 0xAA, sizeof(buf_cmp));
960     memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
961
962     memset(buf, 0xAA, sizeof(buf));
963     ret = GetBitmapBits(hbmp, sizeof(buf), buf);
964     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
965     ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
966
967     hbmp_old = SelectObject(hdc, hbmp);
968
969     ret = GetObject(hbmp, sizeof(bm), &bm);
970     ok(ret == sizeof(bm), "wrong size %d\n", ret);
971
972     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
973     ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
974     ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
975     ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
976     ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
977     ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
978     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
979
980     memset(buf, 0xAA, sizeof(buf));
981     ret = GetBitmapBits(hbmp, sizeof(buf), buf);
982     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
983     ok(!memcmp(buf, buf_cmp, sizeof(buf)), "buffers do not match\n");
984
985     hbmp_old = SelectObject(hdc, hbmp_old);
986     ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
987
988     /* test various buffer sizes for GetObject */
989     ret = GetObject(hbmp, sizeof(bm) * 2, &bm);
990     ok(ret == sizeof(bm), "wrong size %d\n", ret);
991
992     ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
993     ok(ret == 0, "%d != 0\n", ret);
994
995     ret = GetObject(hbmp, 0, &bm);
996     ok(ret == 0, "%d != 0\n", ret);
997
998     ret = GetObject(hbmp, 1, &bm);
999     ok(ret == 0, "%d != 0\n", ret);
1000
1001     DeleteObject(hbmp);
1002     DeleteDC(hdc);
1003 }
1004
1005 static void test_bmBits(void)
1006 {
1007     BYTE bits[4];
1008     HBITMAP hbmp;
1009     BITMAP bmp;
1010
1011     memset(bits, 0, sizeof(bits));
1012     hbmp = CreateBitmap(2, 2, 1, 4, bits);
1013     ok(hbmp != NULL, "CreateBitmap failed\n");
1014
1015     memset(&bmp, 0xFF, sizeof(bmp));
1016     ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1017        "GetObject failed or returned a wrong structure size\n");
1018     ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1019
1020     DeleteObject(hbmp);
1021 }
1022
1023 static void test_GetDIBits_selected_DIB(UINT bpp)
1024 {
1025     HBITMAP dib;
1026     BITMAPINFO * info;
1027     BITMAPINFO * info2;
1028     void * bits;
1029     void * bits2;
1030     UINT dib_size;
1031     HDC dib_dc, dc;
1032     HBITMAP old_bmp;
1033     BOOL equalContents;
1034     UINT i;
1035     int res;
1036
1037     /* Create a DIB section with a color table */
1038
1039     info  = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1040     info2 = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1041     assert(info);
1042     assert(info2);
1043
1044     info->bmiHeader.biSize = sizeof(info->bmiHeader);
1045
1046     /* Choose width and height such that the row length (in bytes)
1047        is a multiple of 4 (makes things easier) */
1048     info->bmiHeader.biWidth = 32;
1049     info->bmiHeader.biHeight = 32;
1050     info->bmiHeader.biPlanes = 1;
1051     info->bmiHeader.biBitCount = bpp;
1052     info->bmiHeader.biCompression = BI_RGB;
1053
1054     for (i=0; i < (1 << bpp); i++)
1055     {
1056         BYTE c = i * (1 << (8 - bpp));
1057         info->bmiColors[i].rgbRed = c;
1058         info->bmiColors[i].rgbGreen = c;
1059         info->bmiColors[i].rgbBlue = c;
1060         info->bmiColors[i].rgbReserved = 0;
1061     }
1062
1063     dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1064     assert(dib);
1065     dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1066
1067     /* Set the bits of the DIB section */
1068     for (i=0; i < dib_size; i++)
1069     {
1070         ((BYTE *)bits)[i] = i % 256;
1071     }
1072
1073     /* Select the DIB into a DC */
1074     dib_dc = CreateCompatibleDC(NULL);
1075     old_bmp = (HBITMAP) SelectObject(dib_dc, dib);
1076     dc = CreateCompatibleDC(NULL);
1077     bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib_size);
1078     assert(bits2);
1079
1080     /* Copy the DIB attributes but not the color table */
1081     memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1082
1083     res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1084     ok(res, "GetDIBits failed\n");
1085
1086     /* Compare the color table and the bits */
1087     equalContents = TRUE;
1088     for (i=0; i < (1 << bpp); i++)
1089     {
1090         if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1091             || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1092             || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1093             || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1094         {
1095             equalContents = FALSE;
1096             break;
1097         }
1098     }
1099     ok(equalContents, "GetDIBits with DIB selected in DC: Invalid DIB color table\n");
1100
1101     equalContents = TRUE;
1102     for (i=0; i < dib_size / sizeof(DWORD); i++)
1103     {
1104         if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1105         {
1106             equalContents = FALSE;
1107             break;
1108         }
1109     }
1110     if (bpp != 1)
1111         ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
1112     else
1113         todo_wine ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
1114
1115     HeapFree(GetProcessHeap(), 0, bits2);
1116     DeleteDC(dc);
1117
1118     SelectObject(dib_dc, old_bmp);
1119     DeleteDC(dib_dc);
1120     DeleteObject(dib);
1121
1122     HeapFree(GetProcessHeap(), 0, info2);
1123     HeapFree(GetProcessHeap(), 0, info);
1124 }
1125
1126 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1127 {
1128     HBITMAP ddb;
1129     BITMAPINFO * info;
1130     BITMAPINFO * info2;
1131     void * bits;
1132     void * bits2;
1133     HDC ddb_dc, dc;
1134     HBITMAP old_bmp;
1135     BOOL equalContents;
1136     UINT width, height;
1137     UINT bpp;
1138     UINT i, j;
1139     int res;
1140
1141     width = height = 16;
1142
1143     /* Create a DDB (device-dependent bitmap) */
1144     if (monochrome)
1145     {
1146         bpp = 1;
1147         ddb = CreateBitmap(width, height, 1, 1, NULL);
1148     }
1149     else
1150     {
1151         HDC screen_dc = GetDC(NULL);
1152         bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1153         ddb = CreateCompatibleBitmap(screen_dc, width, height);
1154         ReleaseDC(NULL, screen_dc);
1155     }
1156
1157     /* Set the pixels */
1158     ddb_dc = CreateCompatibleDC(NULL);
1159     old_bmp = (HBITMAP) SelectObject(ddb_dc, ddb);
1160     for (i = 0; i < width; i++)
1161     {
1162         for (j=0; j < height; j++)
1163         {
1164             BYTE c = (i * width + j) % 256;
1165             SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1166         }
1167     }
1168     SelectObject(ddb_dc, old_bmp);
1169
1170     info  = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1171     info2 = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1172     assert(info);
1173     assert(info2);
1174
1175     info->bmiHeader.biSize = sizeof(info->bmiHeader);
1176     info->bmiHeader.biWidth = width;
1177     info->bmiHeader.biHeight = height;
1178     info->bmiHeader.biPlanes = 1;
1179     info->bmiHeader.biBitCount = bpp;
1180     info->bmiHeader.biCompression = BI_RGB;
1181
1182     dc = CreateCompatibleDC(NULL);
1183
1184     /* Fill in biSizeImage */
1185     GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1186     ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1187
1188     bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1189     bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1190     assert(bits);
1191     assert(bits2);
1192
1193     /* Get the bits */
1194     res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1195     ok(res, "GetDIBits failed\n");
1196
1197     /* Copy the DIB attributes but not the color table */
1198     memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1199
1200     /* Select the DDB into another DC */
1201     old_bmp = (HBITMAP) SelectObject(ddb_dc, ddb);
1202
1203     /* Get the bits */
1204     res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1205     ok(res, "GetDIBits failed\n");
1206
1207     /* Compare the color table and the bits */
1208     if (bpp <= 8)
1209     {
1210         equalContents = TRUE;
1211         for (i=0; i < (1 << bpp); i++)
1212         {
1213             if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1214                 || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1215                 || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1216                 || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1217             {
1218                 equalContents = FALSE;
1219                 break;
1220             }
1221         }
1222         ok(equalContents, "GetDIBits with DDB selected in DC: Got a different color table\n");
1223     }
1224
1225     equalContents = TRUE;
1226     for (i=0; i < info->bmiHeader.biSizeImage / sizeof(DWORD); i++)
1227     {
1228         if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1229         {
1230             equalContents = FALSE;
1231         }
1232     }
1233     ok(equalContents, "GetDIBits with DDB selected in DC: Got different DIB bits\n");
1234
1235     HeapFree(GetProcessHeap(), 0, bits2);
1236     HeapFree(GetProcessHeap(), 0, bits);
1237     DeleteDC(dc);
1238
1239     SelectObject(ddb_dc, old_bmp);
1240     DeleteDC(ddb_dc);
1241     DeleteObject(ddb);
1242
1243     HeapFree(GetProcessHeap(), 0, info2);
1244     HeapFree(GetProcessHeap(), 0, info);
1245 }
1246
1247 static void test_GetDIBits(void)
1248 {
1249     /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1250     static const BYTE bmp_bits_1[16 * 2] =
1251     {
1252         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1253         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1254         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1255         0xff,0xff, 0,0, 0xff,0xff, 0,0
1256     };
1257     /* 4-bytes aligned 1-bit DIB data: 16x16 */
1258     static const BYTE dib_bits_1[16 * 4] =
1259     {
1260         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1261         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1262         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1263         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1264     };
1265     /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1266     static const BYTE bmp_bits_24[16 * 16*3] =
1267     {
1268         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1269         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1270         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1271         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1272         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1273         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1274         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1275         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1276         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1277         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1278         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1279         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1280         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1281         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1282         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1283         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1284         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1285         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1286         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1287         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1288         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1289         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1290         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1291         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1292         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1293         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1294         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1295         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1296         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1297         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1298         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1299         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1300     };
1301     /* 4-bytes aligned 24-bit DIB data: 16x16 */
1302     static const BYTE dib_bits_24[16 * 16*3] =
1303     {
1304         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1305         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1306         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1307         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1308         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1309         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1310         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1311         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1312         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1313         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1314         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1315         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1316         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1317         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1318         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1319         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1320         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1321         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1322         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1323         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1324         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1325         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1326         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1327         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1328         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1329         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1330         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1331         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1332         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1333         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1334         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1335         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1336     };
1337     HBITMAP hbmp;
1338     BITMAP bm;
1339     HDC hdc;
1340     int i, bytes, lines;
1341     BYTE buf[1024];
1342     char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1343     BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1344
1345     hdc = GetDC(0);
1346
1347     /* 1-bit source bitmap data */
1348     hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1349     ok(hbmp != 0, "CreateBitmap failed\n");
1350
1351     memset(&bm, 0xAA, sizeof(bm));
1352     bytes = GetObject(hbmp, sizeof(bm), &bm);
1353     ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1354     ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1355     ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1356     ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1357     ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1358     ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1359     ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1360     ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1361
1362     bytes = GetBitmapBits(hbmp, 0, NULL);
1363     ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1364     bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1365     ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1366     ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1367
1368     /* retrieve 1-bit DIB data */
1369     memset(bi, 0, sizeof(*bi));
1370     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1371     bi->bmiHeader.biWidth = bm.bmWidth;
1372     bi->bmiHeader.biHeight = bm.bmHeight;
1373     bi->bmiHeader.biPlanes = 1;
1374     bi->bmiHeader.biBitCount = 1;
1375     bi->bmiHeader.biCompression = BI_RGB;
1376     bi->bmiHeader.biSizeImage = 0;
1377     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1378     SetLastError(0xdeadbeef);
1379     lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1380     ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1381     ok(GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError());
1382     ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1383
1384     memset(buf, 0xAA, sizeof(buf));
1385     SetLastError(0xdeadbeef);
1386     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1387     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1388        lines, bm.bmHeight, GetLastError());
1389     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1390
1391     /* the color table consists of black and white */
1392     ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1393        bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1394        "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1395        bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1396        bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1397 todo_wine
1398     ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1399        bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1400        "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1401        bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1402        bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1403     for (i = 2; i < 256; i++)
1404     {
1405         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1406            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1407            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1408            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1409            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1410     }
1411
1412     /* returned bits are DWORD aligned and upside down */
1413 todo_wine
1414     ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1415
1416     /* retrieve 24-bit DIB data */
1417     memset(bi, 0, sizeof(*bi));
1418     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1419     bi->bmiHeader.biWidth = bm.bmWidth;
1420     bi->bmiHeader.biHeight = bm.bmHeight;
1421     bi->bmiHeader.biPlanes = 1;
1422     bi->bmiHeader.biBitCount = 24;
1423     bi->bmiHeader.biCompression = BI_RGB;
1424     bi->bmiHeader.biSizeImage = 0;
1425     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1426     memset(buf, 0xAA, sizeof(buf));
1427     SetLastError(0xdeadbeef);
1428     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1429     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1430        lines, bm.bmHeight, GetLastError());
1431     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1432
1433     /* the color table doesn't exist for 24-bit images */
1434     for (i = 0; i < 256; i++)
1435     {
1436         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1437            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1438            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1439            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1440            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1441     }
1442
1443     /* returned bits are DWORD aligned and upside down */
1444 todo_wine
1445     ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1446     DeleteObject(hbmp);
1447
1448     /* 24-bit source bitmap data */
1449     hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1450     ok(hbmp != 0, "CreateBitmap failed\n");
1451     SetLastError(0xdeadbeef);
1452     bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1453     lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1454     ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1455        lines, bm.bmHeight, GetLastError());
1456
1457     memset(&bm, 0xAA, sizeof(bm));
1458     bytes = GetObject(hbmp, sizeof(bm), &bm);
1459     ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1460     ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1461     ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1462     ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1463     ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1464     ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1465     ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1466     ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1467
1468     bytes = GetBitmapBits(hbmp, 0, NULL);
1469     ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1470        bm.bmWidthBytes * bm.bmHeight, bytes);
1471     bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1472     ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1473        bm.bmWidthBytes * bm.bmHeight, bytes);
1474
1475     /* retrieve 1-bit DIB data */
1476     memset(bi, 0, sizeof(*bi));
1477     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1478     bi->bmiHeader.biWidth = bm.bmWidth;
1479     bi->bmiHeader.biHeight = bm.bmHeight;
1480     bi->bmiHeader.biPlanes = 1;
1481     bi->bmiHeader.biBitCount = 1;
1482     bi->bmiHeader.biCompression = BI_RGB;
1483     bi->bmiHeader.biSizeImage = 0;
1484     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1485     memset(buf, 0xAA, sizeof(buf));
1486     SetLastError(0xdeadbeef);
1487     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1488     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1489        lines, bm.bmHeight, GetLastError());
1490     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1), "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1491
1492     /* the color table consists of black and white */
1493     ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1494        bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1495        "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1496        bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1497        bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1498     ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1499        bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1500        "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1501        bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1502        bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1503     for (i = 2; i < 256; i++)
1504     {
1505         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1506            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1507            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1508            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1509            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1510     }
1511
1512     /* returned bits are DWORD aligned and upside down */
1513 todo_wine
1514     ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)), "DIB bits don't match\n");
1515
1516     /* retrieve 24-bit DIB data */
1517     memset(bi, 0, sizeof(*bi));
1518     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1519     bi->bmiHeader.biWidth = bm.bmWidth;
1520     bi->bmiHeader.biHeight = bm.bmHeight;
1521     bi->bmiHeader.biPlanes = 1;
1522     bi->bmiHeader.biBitCount = 24;
1523     bi->bmiHeader.biCompression = BI_RGB;
1524     bi->bmiHeader.biSizeImage = 0;
1525     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1526     memset(buf, 0xAA, sizeof(buf));
1527     SetLastError(0xdeadbeef);
1528     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1529     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1530        lines, bm.bmHeight, GetLastError());
1531     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24), "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1532
1533     /* the color table doesn't exist for 24-bit images */
1534     for (i = 0; i < 256; i++)
1535     {
1536         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1537            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1538            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1539            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1540            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1541     }
1542
1543     /* returned bits are DWORD aligned and upside down */
1544     ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1545     DeleteObject(hbmp);
1546
1547     ReleaseDC(0, hdc);
1548 }
1549
1550 static void test_select_object(void)
1551 {
1552     HDC hdc;
1553     HBITMAP hbm, hbm_old;
1554     INT planes, bpp;
1555
1556     hdc = GetDC(0);
1557     ok(hdc != 0, "GetDC(0) failed\n");
1558     hbm = CreateCompatibleBitmap(hdc, 10, 10);
1559     ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1560
1561     hbm_old = SelectObject(hdc, hbm);
1562     ok(hbm_old == 0, "SelectObject should fail\n");
1563
1564     DeleteObject(hbm);
1565     ReleaseDC(0, hdc);
1566
1567     hdc = CreateCompatibleDC(0);
1568     ok(hdc != 0, "GetDC(0) failed\n");
1569     hbm = CreateCompatibleBitmap(hdc, 10, 10);
1570     ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1571
1572     hbm_old = SelectObject(hdc, hbm);
1573     ok(hbm_old != 0, "SelectObject failed\n");
1574     hbm_old = SelectObject(hdc, hbm_old);
1575     ok(hbm_old == hbm, "SelectObject failed\n");
1576
1577     DeleteObject(hbm);
1578
1579     /* test an 1-bpp bitmap */
1580     planes = GetDeviceCaps(hdc, PLANES);
1581     bpp = 1;
1582
1583     hbm = CreateBitmap(10, 10, planes, bpp, NULL);
1584     ok(hbm != 0, "CreateBitmap failed\n");
1585
1586     hbm_old = SelectObject(hdc, hbm);
1587     ok(hbm_old != 0, "SelectObject failed\n");
1588     hbm_old = SelectObject(hdc, hbm_old);
1589     ok(hbm_old == hbm, "SelectObject failed\n");
1590
1591     DeleteObject(hbm);
1592
1593     /* test a color bitmap that doesn't match the dc's bpp */
1594     planes = GetDeviceCaps(hdc, PLANES);
1595     bpp = GetDeviceCaps(hdc, BITSPIXEL) == 24 ? 8 : 24;
1596
1597     hbm = CreateBitmap(10, 10, planes, bpp, NULL);
1598     ok(hbm != 0, "CreateBitmap failed\n");
1599
1600     hbm_old = SelectObject(hdc, hbm);
1601     ok(hbm_old == 0, "SelectObject should fail\n");
1602
1603     DeleteObject(hbm);
1604
1605     DeleteDC(hdc);
1606 }
1607
1608 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
1609 {
1610     INT ret;
1611     BITMAP bm;
1612
1613     ret = GetObjectType(hbmp);
1614     ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
1615
1616     ret = GetObject(hbmp, 0, 0);
1617     ok_(__FILE__, line)(ret == sizeof(BITMAP) /* XP */ ||
1618                         ret == sizeof(DIBSECTION) /* Win9x */, "object size %d\n", ret);
1619
1620     memset(&bm, 0xDA, sizeof(bm));
1621     SetLastError(0xdeadbeef);
1622     ret = GetObject(hbmp, sizeof(bm), &bm);
1623     if (!ret) /* XP, only for curObj2 */ return;
1624     ok_(__FILE__, line)(ret == sizeof(BITMAP) ||
1625                         ret == sizeof(DIBSECTION) /* Win9x, only for curObj2 */,
1626                         "GetObject returned %d, error %u\n", ret, GetLastError());
1627     ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1628     ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth %d\n", bm.bmWidth);
1629     ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight %d\n", bm.bmHeight);
1630     ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1631     ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1632     ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1633     ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1634 }
1635
1636 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
1637
1638 static void test_CreateBitmap(void)
1639 {
1640     BITMAP bmp;
1641     HDC screenDC = GetDC(0);
1642     HDC hdc = CreateCompatibleDC(screenDC);
1643
1644     /* all of these are the stock monochrome bitmap */
1645     HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
1646     HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
1647     HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
1648     HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
1649     HBITMAP curObj1 = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP);
1650     HBITMAP curObj2 = (HBITMAP)GetCurrentObject(screenDC, OBJ_BITMAP);
1651
1652     /* these 2 are not the stock monochrome bitmap */
1653     HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
1654     HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
1655
1656     HBITMAP old1 = (HBITMAP)SelectObject(hdc, bm2);
1657     HBITMAP old2 = (HBITMAP)SelectObject(screenDC, bm3);
1658     SelectObject(hdc, old1);
1659     SelectObject(screenDC, old2);
1660
1661     ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
1662        "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
1663        bm, bm1, bm4, bm5, curObj1, old1);
1664     ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
1665     ok(bm != curObj2 /* XP */ || bm == curObj2 /* Win9x */,
1666        "0: %p, curObj2 %p\n", bm, curObj2);
1667     ok(old2 == 0, "old2 %p\n", old2);
1668
1669     test_mono_1x1_bmp(bm);
1670     test_mono_1x1_bmp(bm1);
1671     test_mono_1x1_bmp(bm2);
1672     test_mono_1x1_bmp(bm3);
1673     test_mono_1x1_bmp(bm4);
1674     test_mono_1x1_bmp(bm5);
1675     test_mono_1x1_bmp(old1);
1676     test_mono_1x1_bmp(curObj1);
1677     test_mono_1x1_bmp(curObj2);
1678
1679     DeleteObject(bm);
1680     DeleteObject(bm1);
1681     DeleteObject(bm2);
1682     DeleteObject(bm3);
1683     DeleteObject(bm4);
1684     DeleteObject(bm5);
1685
1686     DeleteDC(hdc);
1687     ReleaseDC(0, screenDC);
1688
1689     /* show that Windows ignores the provided bm.bmWidthBytes */
1690     bmp.bmType = 0;
1691     bmp.bmWidth = 1;
1692     bmp.bmHeight = 1;
1693     bmp.bmWidthBytes = 28;
1694     bmp.bmPlanes = 1;
1695     bmp.bmBitsPixel = 1;
1696     bmp.bmBits = NULL;
1697     bm = CreateBitmapIndirect(&bmp);
1698     ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
1699     test_mono_1x1_bmp(bm);
1700     DeleteObject(bm);
1701 }
1702
1703 START_TEST(bitmap)
1704 {
1705     is_win9x = GetWindowLongPtrW(GetDesktopWindow(), GWLP_WNDPROC) == 0;
1706
1707     test_createdibitmap();
1708     test_dibsections();
1709     test_mono_dibsection();
1710     test_bitmap();
1711     test_bmBits();
1712     test_GetDIBits_selected_DIB(1);
1713     test_GetDIBits_selected_DIB(4);
1714     test_GetDIBits_selected_DIB(8);
1715     test_GetDIBits_selected_DDB(TRUE);
1716     test_GetDIBits_selected_DDB(FALSE);
1717     test_GetDIBits();
1718     test_select_object();
1719     test_CreateBitmap();
1720 }