hlink: Set hlink's location to NULL if the empty string is given.
[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 "winerror.h"
29 #include "wingdi.h"
30 #include "winuser.h"
31 #include "mmsystem.h"
32
33 #include "wine/test.h"
34
35 static BOOL (WINAPI *pGdiAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION);
36
37 #define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); }
38
39 static BOOL is_win9x;
40
41 static INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
42 {
43     switch(bpp)
44     {
45     case 1:
46         return 2 * ((bmWidth+15) >> 4);
47
48     case 24:
49         bmWidth *= 3; /* fall through */
50     case 8:
51         return bmWidth + (bmWidth & 1);
52
53     case 32:
54         return bmWidth * 4;
55
56     case 16:
57     case 15:
58         return bmWidth * 2;
59
60     case 4:
61         return 2 * ((bmWidth+3) >> 2);
62
63     default:
64         trace("Unknown depth %d, please report.\n", bpp );
65         assert(0);
66     }
67     return -1;
68 }
69
70 static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHEADER *bmih)
71 {
72     BITMAP bm;
73     BITMAP bma[2];
74     INT ret, width_bytes;
75     BYTE buf[512], buf_cmp[512];
76     DWORD gle;
77
78     ret = GetObject(hbm, sizeof(bm), &bm);
79     ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
80
81     ok(bm.bmType == 0 || broken(bm.bmType == 21072 /* Win9x */), "wrong bm.bmType %d\n", bm.bmType);
82     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
83     ok(bm.bmHeight == bmih->biHeight, "wrong bm.bmHeight %d\n", bm.bmHeight);
84     width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
85     ok(bm.bmWidthBytes == width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, width_bytes);
86     ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
87     ok(bm.bmBitsPixel == expected_depth, "wrong bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, expected_depth);
88     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
89
90     assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
91     assert(sizeof(buf) == sizeof(buf_cmp));
92
93     SetLastError(0xdeadbeef);
94     ret = GetBitmapBits(hbm, 0, NULL);
95     gle=GetLastError();
96     ok(ret == bm.bmWidthBytes * bm.bmHeight || (ret == 0 && gle == ERROR_INVALID_PARAMETER /* Win9x */), "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
97
98     memset(buf_cmp, 0xAA, sizeof(buf_cmp));
99     memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
100
101     memset(buf, 0xAA, sizeof(buf));
102     ret = GetBitmapBits(hbm, sizeof(buf), buf);
103     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
104     ok(!memcmp(buf, buf_cmp, sizeof(buf)) ||
105        broken(memcmp(buf, buf_cmp, sizeof(buf))), /* win9x doesn't init the bitmap bits */
106         "buffers do not match, depth %d\n", bmih->biBitCount);
107
108     /* test various buffer sizes for GetObject */
109     ret = GetObject(hbm, sizeof(*bma) * 2, bma);
110     ok(ret == sizeof(*bma) || broken(ret == sizeof(*bma) * 2 /* Win9x */), "wrong size %d\n", ret);
111
112     ret = GetObject(hbm, sizeof(bm) / 2, &bm);
113     ok(ret == 0 || broken(ret == sizeof(bm) / 2 /* Win9x */), "%d != 0\n", ret);
114
115     ret = GetObject(hbm, 0, &bm);
116     ok(ret == 0, "%d != 0\n", ret);
117
118     ret = GetObject(hbm, 1, &bm);
119     ok(ret == 0 || broken(ret == 1 /* Win9x */), "%d != 0\n", ret);
120
121     /* Don't trust Win9x not to try to write to NULL */
122     if (ret == 0)
123     {
124         ret = GetObject(hbm, 0, NULL);
125         ok(ret == sizeof(bm), "wrong size %d\n", ret);
126     }
127 }
128
129 static void test_createdibitmap(void)
130 {
131     HDC hdc, hdcmem;
132     BITMAPINFOHEADER bmih;
133     BITMAPINFO bm;
134     HBITMAP hbm, hbm_colour, hbm_old;
135     INT screen_depth;
136     DWORD pixel;
137
138     hdc = GetDC(0);
139     screen_depth = GetDeviceCaps(hdc, BITSPIXEL);
140     memset(&bmih, 0, sizeof(bmih));
141     bmih.biSize = sizeof(bmih);
142     bmih.biWidth = 10;
143     bmih.biHeight = 10;
144     bmih.biPlanes = 1;
145     bmih.biBitCount = 32;
146     bmih.biCompression = BI_RGB;
147
148     hbm = CreateDIBitmap(hdc, NULL, CBM_INIT, NULL, NULL, 0);
149     ok(hbm == NULL, "CreateDIBitmap should fail\n");
150     hbm = CreateDIBitmap(hdc, NULL, 0, NULL, NULL, 0);
151     ok(hbm == NULL, "CreateDIBitmap should fail\n");
152
153     /* First create an un-initialised bitmap.  The depth of the bitmap
154        should match that of the hdc and not that supplied in bmih.
155     */
156
157     /* First try 32 bits */
158     hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
159     ok(hbm != NULL, "CreateDIBitmap failed\n");
160     test_bitmap_info(hbm, screen_depth, &bmih);
161     DeleteObject(hbm);
162     
163     /* Then 16 */
164     bmih.biBitCount = 16;
165     hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
166     ok(hbm != NULL, "CreateDIBitmap failed\n");
167     test_bitmap_info(hbm, screen_depth, &bmih);
168     DeleteObject(hbm);
169
170     /* Then 1 */
171     bmih.biBitCount = 1;
172     hbm = CreateDIBitmap(hdc, &bmih, 0, NULL, NULL, 0);
173     ok(hbm != NULL, "CreateDIBitmap failed\n");
174     test_bitmap_info(hbm, screen_depth, &bmih);
175     DeleteObject(hbm);
176
177     /* Now with a monochrome dc we expect a monochrome bitmap */
178     hdcmem = CreateCompatibleDC(hdc);
179
180     /* First try 32 bits */
181     bmih.biBitCount = 32;
182     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
183     ok(hbm != NULL, "CreateDIBitmap failed\n");
184     test_bitmap_info(hbm, 1, &bmih);
185     DeleteObject(hbm);
186     
187     /* Then 16 */
188     bmih.biBitCount = 16;
189     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
190     ok(hbm != NULL, "CreateDIBitmap failed\n");
191     test_bitmap_info(hbm, 1, &bmih);
192     DeleteObject(hbm);
193     
194     /* Then 1 */
195     bmih.biBitCount = 1;
196     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
197     ok(hbm != NULL, "CreateDIBitmap failed\n");
198     test_bitmap_info(hbm, 1, &bmih);
199     DeleteObject(hbm);
200
201     /* Now select a polychrome bitmap into the dc and we expect
202        screen_depth bitmaps again */
203     hbm_colour = CreateCompatibleBitmap(hdc, bmih.biWidth, bmih.biHeight);
204     test_bitmap_info(hbm_colour, screen_depth, &bmih);
205     hbm_old = SelectObject(hdcmem, hbm_colour);
206
207     /* First try 32 bits */
208     bmih.biBitCount = 32;
209     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
210     ok(hbm != NULL, "CreateDIBitmap failed\n");
211     test_bitmap_info(hbm, screen_depth, &bmih);
212     DeleteObject(hbm);
213     
214     /* Then 16 */
215     bmih.biBitCount = 16;
216     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
217     ok(hbm != NULL, "CreateDIBitmap failed\n");
218     test_bitmap_info(hbm, screen_depth, &bmih);
219     DeleteObject(hbm);
220     
221     /* Then 1 */
222     bmih.biBitCount = 1;
223     hbm = CreateDIBitmap(hdcmem, &bmih, 0, NULL, NULL, 0);
224     ok(hbm != NULL, "CreateDIBitmap failed\n");
225     test_bitmap_info(hbm, screen_depth, &bmih);
226     DeleteObject(hbm);
227
228     SelectObject(hdcmem, hbm_old);
229     DeleteObject(hbm_colour);
230     DeleteDC(hdcmem);
231
232     /* If hdc == 0 then we get a 1 bpp bitmap */
233     if (!is_win9x) {
234         bmih.biBitCount = 32;
235         hbm = CreateDIBitmap(0, &bmih, 0, NULL, NULL, 0);
236         ok(hbm != NULL, "CreateDIBitmap failed\n");
237         test_bitmap_info(hbm, 1, &bmih);
238         DeleteObject(hbm);
239     }
240
241     /* Test how formats are converted */
242     pixel = 0xffffffff;
243     bmih.biBitCount = 1;
244     bmih.biWidth = 1;
245     bmih.biHeight = 1;
246
247     memset(&bm, 0, sizeof(bm));
248     bm.bmiHeader.biSize = sizeof(bm.bmiHeader);
249     bm.bmiHeader.biWidth = 1;
250     bm.bmiHeader.biHeight = 1;
251     bm.bmiHeader.biPlanes = 1;
252     bm.bmiHeader.biBitCount= 24;
253     bm.bmiHeader.biCompression= BI_RGB;
254     bm.bmiHeader.biSizeImage = 0;
255     hbm = CreateDIBitmap(hdc, &bmih, CBM_INIT, &pixel, &bm, DIB_RGB_COLORS);
256     ok(hbm != NULL, "CreateDIBitmap failed\n");
257
258     pixel = 0xdeadbeef;
259     bm.bmiHeader.biBitCount= 32;
260     GetDIBits(hdc, hbm, 0, 1, &pixel, &bm, DIB_RGB_COLORS);
261     ok(pixel == 0x00ffffff, "Reading a 32 bit pixel from a DDB returned %08x\n", pixel);
262     DeleteObject(hbm);
263
264     ReleaseDC(0, hdc);
265 }
266
267 static INT DIB_GetWidthBytes( int width, int bpp )
268 {
269     int words;
270
271     switch (bpp)
272     {
273         case 1:  words = (width + 31) / 32; break;
274         case 4:  words = (width + 7) / 8; break;
275         case 8:  words = (width + 3) / 4; break;
276         case 15:
277         case 16: words = (width + 1) / 2; break;
278         case 24: words = (width * 3 + 3)/4; break;
279         case 32: words = width; break;
280
281         default:
282             words=0;
283             trace("Unknown depth %d, please report.\n", bpp );
284             assert(0);
285             break;
286     }
287     return 4 * words;
288 }
289
290 static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER *bmih)
291 {
292     BITMAP bm;
293     BITMAP bma[2];
294     DIBSECTION ds;
295     DIBSECTION dsa[2];
296     INT ret, bm_width_bytes, dib_width_bytes;
297     BYTE *buf;
298
299     ret = GetObject(hbm, sizeof(bm), &bm);
300     ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
301
302     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
303     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
304     ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
305     dib_width_bytes = DIB_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
306     bm_width_bytes = BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel);
307     if (bm.bmWidthBytes != dib_width_bytes) /* Win2k bug */
308         ok(bm.bmWidthBytes == bm_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, bm_width_bytes);
309     else
310         ok(bm.bmWidthBytes == dib_width_bytes, "wrong bm.bmWidthBytes %d != %d\n", bm.bmWidthBytes, dib_width_bytes);
311     ok(bm.bmPlanes == bmih->biPlanes, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
312     ok(bm.bmBitsPixel == bmih->biBitCount, "bm.bmBitsPixel %d != %d\n", bm.bmBitsPixel, bmih->biBitCount);
313     ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
314
315     buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight + 4096);
316
317     /* GetBitmapBits returns not 32-bit aligned data */
318     SetLastError(0xdeadbeef);
319     ret = GetBitmapBits(hbm, 0, NULL);
320     ok(ret == bm_width_bytes * bm.bmHeight ||
321         broken(ret == 0 && GetLastError() == ERROR_INVALID_PARAMETER), /* Win9x */
322         "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
323
324     memset(buf, 0xAA, bm.bmWidthBytes * bm.bmHeight + 4096);
325     ret = GetBitmapBits(hbm, bm.bmWidthBytes * bm.bmHeight + 4096, buf);
326     ok(ret == bm_width_bytes * bm.bmHeight, "%d != %d\n", ret, bm_width_bytes * bm.bmHeight);
327
328     HeapFree(GetProcessHeap(), 0, buf);
329
330     /* test various buffer sizes for GetObject */
331     memset(&ds, 0xAA, sizeof(ds));
332     ret = GetObject(hbm, sizeof(*bma) * 2, bma);
333     ok(ret == sizeof(*bma) || broken(ret == sizeof(*bma) * 2 /* Win9x */), "wrong size %d\n", ret);
334     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
335     ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
336     ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
337
338     ret = GetObject(hbm, sizeof(bm) / 2, &bm);
339     ok(ret == 0 || broken(ret == sizeof(bm) / 2 /* Win9x */), "%d != 0\n", ret);
340
341     ret = GetObject(hbm, 0, &bm);
342     ok(ret == 0, "%d != 0\n", ret);
343
344     ret = GetObject(hbm, 1, &bm);
345     ok(ret == 0 || broken(ret ==  1 /* Win9x */), "%d != 0\n", ret);
346
347     /* test various buffer sizes for GetObject */
348     ret = GetObject(hbm, 0, NULL);
349     ok(ret == sizeof(bm) || broken(ret == sizeof(DIBSECTION) /* Win9x */), "wrong size %d\n", ret);
350
351     ret = GetObject(hbm, sizeof(*dsa) * 2, dsa);
352     ok(ret == sizeof(*dsa) || broken(ret == sizeof(*dsa) * 2 /* Win9x */), "wrong size %d\n", ret);
353
354     memset(&ds, 0xAA, sizeof(ds));
355     ret = GetObject(hbm, sizeof(ds), &ds);
356     ok(ret == sizeof(ds), "wrong size %d\n", ret);
357
358     ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
359     if (ds.dsBm.bmWidthBytes != bm_width_bytes) /* Win2k bug */
360         ok(ds.dsBmih.biSizeImage == ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight, "%u != %u\n",
361            ds.dsBmih.biSizeImage, ds.dsBm.bmWidthBytes * ds.dsBm.bmHeight);
362     ok(bmih->biSizeImage == 0, "%u != 0\n", bmih->biSizeImage);
363     ds.dsBmih.biSizeImage = 0;
364
365     ok(ds.dsBmih.biSize == bmih->biSize, "%u != %u\n", ds.dsBmih.biSize, bmih->biSize);
366     ok(ds.dsBmih.biWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
367     ok(ds.dsBmih.biHeight == abs(bmih->biHeight) ||
368        broken(ds.dsBmih.biHeight == bmih->biHeight), /* Win9x/WinMe */
369        "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
370     ok(ds.dsBmih.biPlanes == bmih->biPlanes, "%u != %u\n", ds.dsBmih.biPlanes, bmih->biPlanes);
371     ok(ds.dsBmih.biBitCount == bmih->biBitCount, "%u != %u\n", ds.dsBmih.biBitCount, bmih->biBitCount);
372     ok(ds.dsBmih.biCompression == bmih->biCompression, "%u != %u\n", ds.dsBmih.biCompression, bmih->biCompression);
373     ok(ds.dsBmih.biSizeImage == bmih->biSizeImage, "%u != %u\n", ds.dsBmih.biSizeImage, bmih->biSizeImage);
374     ok(ds.dsBmih.biXPelsPerMeter == bmih->biXPelsPerMeter, "%d != %d\n", ds.dsBmih.biXPelsPerMeter, bmih->biXPelsPerMeter);
375     ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%d != %d\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
376
377     memset(&ds, 0xAA, sizeof(ds));
378     ret = GetObject(hbm, sizeof(ds) - 4, &ds);
379     ok(ret == sizeof(ds.dsBm) || broken(ret == (sizeof(ds) - 4) /* Win9x */), "wrong size %d\n", ret);
380     ok(ds.dsBm.bmWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
381     ok(ds.dsBm.bmHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
382     ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
383
384     ret = GetObject(hbm, 0, &ds);
385     ok(ret == 0, "%d != 0\n", ret);
386
387     ret = GetObject(hbm, 1, &ds);
388     ok(ret == 0 || broken(ret == 1 /* Win9x */), "%d != 0\n", ret);
389 }
390
391 #define test_color_todo(got, exp, txt, todo) \
392     if (!todo && got != exp && screen_depth < 24) { \
393       todo_wine ok(0, #txt " failed at %d-bit screen depth: got 0x%06x expected 0x%06x - skipping DIB tests\n", \
394                    screen_depth, (UINT)got, (UINT)exp); \
395       return; \
396     } else if (todo) todo_wine { ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp); } \
397     else ok(got == exp, #txt " failed: got 0x%06x expected 0x%06x\n", (UINT)got, (UINT)exp) \
398
399 #define test_color(hdc, color, exp, todo_setp, todo_getp) \
400 { \
401     COLORREF c; \
402     c = SetPixel(hdc, 0, 0, color); \
403     if (!is_win9x) { test_color_todo(c, exp, SetPixel, todo_setp); } \
404     c = GetPixel(hdc, 0, 0); \
405     test_color_todo(c, exp, GetPixel, todo_getp); \
406 }
407
408 static void test_dib_bits_access( HBITMAP hdib, void *bits )
409 {
410     MEMORY_BASIC_INFORMATION info;
411     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
412     DWORD data[256];
413     BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
414     HDC hdc = GetDC(0);
415     char filename[MAX_PATH];
416     HANDLE file;
417     DWORD written;
418     INT ret;
419
420     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
421         "VirtualQuery failed\n");
422     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
423     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
424     ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
425     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
426     ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
427     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
428
429     memset( pbmi, 0, sizeof(bmibuf) );
430     memset( data, 0xcc, sizeof(data) );
431     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
432     pbmi->bmiHeader.biHeight = 16;
433     pbmi->bmiHeader.biWidth = 16;
434     pbmi->bmiHeader.biBitCount = 32;
435     pbmi->bmiHeader.biPlanes = 1;
436     pbmi->bmiHeader.biCompression = BI_RGB;
437
438     ret = SetDIBits( hdc, hdib, 0, 16, data, pbmi, DIB_RGB_COLORS );
439     ok(ret == 16 ||
440        broken(ret == 0), /* win9x */
441        "SetDIBits failed: expected 16 got %d\n", ret);
442
443     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
444         "VirtualQuery failed\n");
445     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
446     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
447     ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
448     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
449     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
450     /* it has been protected now */
451     todo_wine ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
452
453     /* try writing protected bits to a file */
454
455     GetTempFileNameA( ".", "dib", 0, filename );
456     file = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
457                         CREATE_ALWAYS, 0, 0 );
458     ok( file != INVALID_HANDLE_VALUE, "failed to open %s error %u\n", filename, GetLastError() );
459     ret = WriteFile( file, bits, 8192, &written, NULL );
460     ok( ret, "WriteFile failed error %u\n", GetLastError() );
461     if (ret) ok( written == 8192, "only wrote %u bytes\n", written );
462     CloseHandle( file );
463     DeleteFileA( filename );
464 }
465
466 static void test_dibsections(void)
467 {
468     HDC hdc, hdcmem, hdcmem2;
469     HBITMAP hdib, oldbm, hdib2, oldbm2;
470     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
471     char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
472     BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
473     BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
474     HBITMAP hcoredib;
475     char coreBits[256];
476     BYTE *bits;
477     RGBQUAD rgb[256];
478     int ret;
479     char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
480     LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
481     WORD *index;
482     DWORD *bits32;
483     HPALETTE hpal, oldpal;
484     DIBSECTION dibsec;
485     COLORREF c0, c1;
486     int i;
487     int screen_depth;
488     MEMORY_BASIC_INFORMATION info;
489
490     hdc = GetDC(0);
491     screen_depth = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
492
493     memset(pbmi, 0, sizeof(bmibuf));
494     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
495     pbmi->bmiHeader.biHeight = 100;
496     pbmi->bmiHeader.biWidth = 512;
497     pbmi->bmiHeader.biBitCount = 24;
498     pbmi->bmiHeader.biPlanes = 1;
499     pbmi->bmiHeader.biCompression = BI_RGB;
500
501     SetLastError(0xdeadbeef);
502
503     /* invalid pointer for BITMAPINFO
504        (*bits should be NULL on error) */
505     bits = (BYTE*)0xdeadbeef;
506     hdib = CreateDIBSection(hdc, NULL, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
507     ok(hdib == NULL && bits == NULL, "CreateDIBSection failed for invalid parameter: bmi == 0x0\n");
508
509     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
510     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
511     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
512     ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
513
514     /* test the DIB memory */
515     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
516         "VirtualQuery failed\n");
517     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
518     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
519     ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
520     ok(info.RegionSize == 0x26000, "0x%lx != 0x26000\n", info.RegionSize);
521     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
522     ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
523     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
524
525     test_dib_bits_access( hdib, bits );
526
527     test_dib_info(hdib, bits, &pbmi->bmiHeader);
528     DeleteObject(hdib);
529
530     /* Test a top-down DIB. */
531     pbmi->bmiHeader.biHeight = -100;
532     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
533     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
534     test_dib_info(hdib, bits, &pbmi->bmiHeader);
535     DeleteObject(hdib);
536
537     pbmi->bmiHeader.biHeight = 100;
538     pbmi->bmiHeader.biBitCount = 8;
539     pbmi->bmiHeader.biCompression = BI_RLE8;
540     SetLastError(0xdeadbeef);
541     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
542     ok(hdib == NULL, "CreateDIBSection should fail when asked to create a compressed DIB section\n");
543     ok(GetLastError() == 0xdeadbeef, "wrong error %d\n", GetLastError());
544
545     pbmi->bmiHeader.biBitCount = 16;
546     pbmi->bmiHeader.biCompression = BI_BITFIELDS;
547     ((PDWORD)pbmi->bmiColors)[0] = 0xf800;
548     ((PDWORD)pbmi->bmiColors)[1] = 0x07e0;
549     ((PDWORD)pbmi->bmiColors)[2] = 0x001f;
550     SetLastError(0xdeadbeef);
551     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
552     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
553
554     /* test the DIB memory */
555     ok(VirtualQuery(bits, &info, sizeof(info)) == sizeof(info),
556         "VirtualQuery failed\n");
557     ok(info.BaseAddress == bits, "%p != %p\n", info.BaseAddress, bits);
558     ok(info.AllocationBase == bits, "%p != %p\n", info.AllocationBase, bits);
559     ok(info.AllocationProtect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.AllocationProtect);
560     ok(info.RegionSize == 0x19000, "0x%lx != 0x19000\n", info.RegionSize);
561     ok(info.State == MEM_COMMIT, "%x != MEM_COMMIT\n", info.State);
562     ok(info.Protect == PAGE_READWRITE, "%x != PAGE_READWRITE\n", info.Protect);
563     ok(info.Type == MEM_PRIVATE, "%x != MEM_PRIVATE\n", info.Type);
564
565     test_dib_info(hdib, bits, &pbmi->bmiHeader);
566     DeleteObject(hdib);
567
568     memset(pbmi, 0, sizeof(bmibuf));
569     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
570     pbmi->bmiHeader.biHeight = 16;
571     pbmi->bmiHeader.biWidth = 16;
572     pbmi->bmiHeader.biBitCount = 1;
573     pbmi->bmiHeader.biPlanes = 1;
574     pbmi->bmiHeader.biCompression = BI_RGB;
575     pbmi->bmiColors[0].rgbRed = 0xff;
576     pbmi->bmiColors[0].rgbGreen = 0;
577     pbmi->bmiColors[0].rgbBlue = 0;
578     pbmi->bmiColors[1].rgbRed = 0;
579     pbmi->bmiColors[1].rgbGreen = 0;
580     pbmi->bmiColors[1].rgbBlue = 0xff;
581
582     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
583     ok(hdib != NULL, "CreateDIBSection failed\n");
584     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
585     ok(dibsec.dsBmih.biClrUsed == 2,
586         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
587
588     /* Test if the old BITMAPCOREINFO structure is supported */    
589         
590     pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
591     pbci->bmciHeader.bcBitCount = 0;
592
593     if (!is_win9x) {
594         ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
595         ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
596         ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
597             && (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
598         "GetDIBits did't fill in the BITMAPCOREHEADER structure properly\n");
599
600         ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
601         ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
602         ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
603             (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
604             (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
605             "The color table has not been translated to the old BITMAPCOREINFO format\n");
606
607         hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
608         ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
609
610         ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
611         ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
612         ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
613         ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
614             (pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
615             (pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
616             "The color table has not been translated to the old BITMAPCOREINFO format\n");
617
618         DeleteObject(hcoredib);
619     }
620
621     hdcmem = CreateCompatibleDC(hdc);
622     oldbm = SelectObject(hdcmem, hdib);
623
624     ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
625     ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
626     ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
627        "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
628        rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
629        rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
630
631     c0 = RGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen, pbmi->bmiColors[0].rgbBlue);
632     c1 = RGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen, pbmi->bmiColors[1].rgbBlue);
633
634     test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
635     test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
636     test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
637     test_color(hdcmem, PALETTEINDEX(0), c0, 1, 1);
638     test_color(hdcmem, PALETTEINDEX(1), c0, 1, 1);
639     test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
640     test_color(hdcmem, PALETTERGB(pbmi->bmiColors[0].rgbRed, pbmi->bmiColors[0].rgbGreen,
641         pbmi->bmiColors[0].rgbBlue), c0, 1, 1);
642     test_color(hdcmem, PALETTERGB(pbmi->bmiColors[1].rgbRed, pbmi->bmiColors[1].rgbGreen,
643         pbmi->bmiColors[1].rgbBlue), c1, 1, 1);
644     test_color(hdcmem, PALETTERGB(0, 0, 0), c0, 1, 1);
645     test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
646     test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c1, 1, 1);
647
648     SelectObject(hdcmem, oldbm);
649     DeleteObject(hdib);
650
651     pbmi->bmiColors[0].rgbRed = 0xff;
652     pbmi->bmiColors[0].rgbGreen = 0xff;
653     pbmi->bmiColors[0].rgbBlue = 0xff;
654     pbmi->bmiColors[1].rgbRed = 0;
655     pbmi->bmiColors[1].rgbGreen = 0;
656     pbmi->bmiColors[1].rgbBlue = 0;
657
658     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
659     ok(hdib != NULL, "CreateDIBSection failed\n");
660
661     test_dib_info(hdib, bits, &pbmi->bmiHeader);
662
663     oldbm = SelectObject(hdcmem, hdib);
664
665     ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
666     ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
667     ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
668        "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
669        rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
670        rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
671
672     SelectObject(hdcmem, oldbm);
673     test_dib_info(hdib, bits, &pbmi->bmiHeader);
674     DeleteObject(hdib);
675
676     pbmi->bmiHeader.biBitCount = 4;
677     for (i = 0; i < 16; i++) {
678         pbmi->bmiColors[i].rgbRed = i;
679         pbmi->bmiColors[i].rgbGreen = 16-i;
680         pbmi->bmiColors[i].rgbBlue = 0;
681     }
682     hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
683     ok(hdib != NULL, "CreateDIBSection failed\n");
684     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
685     ok(dibsec.dsBmih.biClrUsed == 16,
686        "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
687     test_dib_info(hdib, bits, &pbmi->bmiHeader);
688     DeleteObject(hdib);
689
690     pbmi->bmiHeader.biBitCount = 8;
691
692     for (i = 0; i < 128; i++) {
693         pbmi->bmiColors[i].rgbRed = 255 - i * 2;
694         pbmi->bmiColors[i].rgbGreen = i * 2;
695         pbmi->bmiColors[i].rgbBlue = 0;
696         pbmi->bmiColors[255 - i].rgbRed = 0;
697         pbmi->bmiColors[255 - i].rgbGreen = i * 2;
698         pbmi->bmiColors[255 - i].rgbBlue = 255 - i * 2;
699     }
700     hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
701     ok(hdib != NULL, "CreateDIBSection failed\n");
702     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
703     ok(dibsec.dsBmih.biClrUsed == 256,
704         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
705
706     oldbm = SelectObject(hdcmem, hdib);
707
708     for (i = 0; i < 256; i++) {
709         test_color(hdcmem, DIBINDEX(i), 
710             RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
711         test_color(hdcmem, PALETTERGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 
712             RGB(pbmi->bmiColors[i].rgbRed, pbmi->bmiColors[i].rgbGreen, pbmi->bmiColors[i].rgbBlue), 0, 0);
713     }
714
715     SelectObject(hdcmem, oldbm);
716     test_dib_info(hdib, bits, &pbmi->bmiHeader);
717     DeleteObject(hdib);
718
719     pbmi->bmiHeader.biBitCount = 1;
720
721     /* Now create a palette and a palette indexed dib section */
722     memset(plogpal, 0, sizeof(logpalbuf));
723     plogpal->palVersion = 0x300;
724     plogpal->palNumEntries = 2;
725     plogpal->palPalEntry[0].peRed = 0xff;
726     plogpal->palPalEntry[0].peBlue = 0xff;
727     plogpal->palPalEntry[1].peGreen = 0xff;
728
729     index = (WORD*)pbmi->bmiColors;
730     *index++ = 0;
731     *index = 1;
732     hpal = CreatePalette(plogpal);
733     ok(hpal != NULL, "CreatePalette failed\n");
734     oldpal = SelectPalette(hdc, hpal, TRUE);
735     hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
736     ok(hdib != NULL, "CreateDIBSection failed\n");
737     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
738     ok(dibsec.dsBmih.biClrUsed == 2 ||
739        broken(dibsec.dsBmih.biClrUsed == 0), /* win9x */
740         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
741
742     /* The colour table has already been grabbed from the dc, so we select back the
743        old palette */
744
745     SelectPalette(hdc, oldpal, TRUE);
746     oldbm = SelectObject(hdcmem, hdib);
747     oldpal = SelectPalette(hdcmem, hpal, TRUE);
748
749     ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
750     ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
751     ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
752        rgb[1].rgbRed == 0    && rgb[1].rgbBlue == 0    && rgb[1].rgbGreen == 0xff,
753        "GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
754        rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
755        rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
756
757     c0 = RGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen, plogpal->palPalEntry[0].peBlue);
758     c1 = RGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen, plogpal->palPalEntry[1].peBlue);
759
760     test_color(hdcmem, DIBINDEX(0), c0, 0, 1);
761     test_color(hdcmem, DIBINDEX(1), c1, 0, 1);
762     test_color(hdcmem, DIBINDEX(2), c0, 1, 1);
763     test_color(hdcmem, PALETTEINDEX(0), c0, 0, 1);
764     test_color(hdcmem, PALETTEINDEX(1), c1, 0, 1);
765     test_color(hdcmem, PALETTEINDEX(2), c0, 1, 1);
766     test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[0].peRed, plogpal->palPalEntry[0].peGreen,
767         plogpal->palPalEntry[0].peBlue), c0, 1, 1);
768     test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[1].peRed, plogpal->palPalEntry[1].peGreen,
769         plogpal->palPalEntry[1].peBlue), c1, 1, 1);
770     test_color(hdcmem, PALETTERGB(0, 0, 0), c1, 1, 1);
771     test_color(hdcmem, PALETTERGB(0xff, 0xff, 0xff), c0, 1, 1);
772     test_color(hdcmem, PALETTERGB(0, 0, 0xfe), c0, 1, 1);
773     test_color(hdcmem, PALETTERGB(0, 1, 0), c1, 1, 1);
774     test_color(hdcmem, PALETTERGB(0x3f, 0, 0x3f), c1, 1, 1);
775     test_color(hdcmem, PALETTERGB(0x40, 0, 0x40), c0, 1, 1);
776
777     /* Bottom and 2nd row from top green, everything else magenta */
778     bits[0] = bits[1] = 0xff;
779     bits[13 * 4] = bits[13*4 + 1] = 0xff;
780
781     test_dib_info(hdib, bits, &pbmi->bmiHeader);
782
783     pbmi->bmiHeader.biBitCount = 32;
784
785     hdib2 = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, (void **)&bits32, NULL, 0);
786     ok(hdib2 != NULL, "CreateDIBSection failed\n");
787     hdcmem2 = CreateCompatibleDC(hdc);
788     oldbm2 = SelectObject(hdcmem2, hdib2);
789
790     BitBlt(hdcmem2, 0, 0, 16,16, hdcmem, 0, 0, SRCCOPY);
791
792     ok(bits32[0] == 0xff00, "lower left pixel is %08x\n", bits32[0]);
793     ok(bits32[17] == 0xff00ff ||
794        broken(bits32[17] == 0x00ff00), /* Intermittent on Win9x/ME */
795        "bottom but one, left pixel is %08x\n", bits32[17]);
796
797     SelectObject(hdcmem2, oldbm2);
798     test_dib_info(hdib2, bits32, &pbmi->bmiHeader);
799     DeleteObject(hdib2);
800
801     SelectObject(hdcmem, oldbm);
802     SelectObject(hdcmem, oldpal);
803     DeleteObject(hdib);
804     DeleteObject(hpal);
805
806
807     pbmi->bmiHeader.biBitCount = 8;
808
809     memset(plogpal, 0, sizeof(logpalbuf));
810     plogpal->palVersion = 0x300;
811     plogpal->palNumEntries = 256;
812
813     for (i = 0; i < 128; i++) {
814         plogpal->palPalEntry[i].peRed = 255 - i * 2;
815         plogpal->palPalEntry[i].peBlue = i * 2;
816         plogpal->palPalEntry[i].peGreen = 0;
817         plogpal->palPalEntry[255 - i].peRed = 0;
818         plogpal->palPalEntry[255 - i].peGreen = i * 2;
819         plogpal->palPalEntry[255 - i].peBlue = 255 - i * 2;
820     }
821
822     index = (WORD*)pbmi->bmiColors;
823     for (i = 0; i < 256; i++) {
824         *index++ = i;
825     }
826
827     hpal = CreatePalette(plogpal);
828     ok(hpal != NULL, "CreatePalette failed\n");
829     oldpal = SelectPalette(hdc, hpal, TRUE);
830     hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
831     ok(hdib != NULL, "CreateDIBSection failed\n");
832     ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
833     ok(dibsec.dsBmih.biClrUsed == 256 ||
834        broken(dibsec.dsBmih.biClrUsed == 0), /* win9x */
835         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
836
837     test_dib_info(hdib, bits, &pbmi->bmiHeader);
838
839     SelectPalette(hdc, oldpal, TRUE);
840     oldbm = SelectObject(hdcmem, hdib);
841     oldpal = SelectPalette(hdcmem, hpal, TRUE);
842
843     ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
844     ok(ret == 256, "GetDIBColorTable returned %d\n", ret);
845     for (i = 0; i < 256; i++) {
846         ok(rgb[i].rgbRed == plogpal->palPalEntry[i].peRed && 
847             rgb[i].rgbBlue == plogpal->palPalEntry[i].peBlue && 
848             rgb[i].rgbGreen == plogpal->palPalEntry[i].peGreen, 
849             "GetDIBColorTable returns table %d: r%02x g%02x b%02x res%02x\n",
850             i, rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue, rgb[i].rgbReserved);
851     }
852
853     for (i = 0; i < 256; i++) {
854         test_color(hdcmem, DIBINDEX(i), 
855             RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
856         test_color(hdcmem, PALETTEINDEX(i), 
857             RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
858         test_color(hdcmem, PALETTERGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 
859             RGB(plogpal->palPalEntry[i].peRed, plogpal->palPalEntry[i].peGreen, plogpal->palPalEntry[i].peBlue), 0, 0);
860     }
861
862     SelectPalette(hdcmem, oldpal, TRUE);
863     SelectObject(hdcmem, oldbm);
864     DeleteObject(hdib);
865     DeleteObject(hpal);
866
867
868     DeleteDC(hdcmem);
869     ReleaseDC(0, hdc);
870 }
871
872 static void test_mono_dibsection(void)
873 {
874     HDC hdc, memdc;
875     HBITMAP old_bm, mono_ds;
876     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
877     BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
878     BYTE bits[10 * 4];
879     BYTE *ds_bits;
880     int num;
881
882     hdc = GetDC(0);
883
884     memdc = CreateCompatibleDC(hdc);
885
886     memset(pbmi, 0, sizeof(bmibuf));
887     pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
888     pbmi->bmiHeader.biHeight = 10;
889     pbmi->bmiHeader.biWidth = 10;
890     pbmi->bmiHeader.biBitCount = 1;
891     pbmi->bmiHeader.biPlanes = 1;
892     pbmi->bmiHeader.biCompression = BI_RGB;
893     pbmi->bmiColors[0].rgbRed = 0xff;
894     pbmi->bmiColors[0].rgbGreen = 0xff;
895     pbmi->bmiColors[0].rgbBlue = 0xff;
896     pbmi->bmiColors[1].rgbRed = 0x0;
897     pbmi->bmiColors[1].rgbGreen = 0x0;
898     pbmi->bmiColors[1].rgbBlue = 0x0;
899
900     /*
901      * First dib section is 'inverted' ie color[0] is white, color[1] is black
902      */
903
904     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
905     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
906     old_bm = SelectObject(memdc, mono_ds);
907
908     /* black border, white interior */
909     Rectangle(memdc, 0, 0, 10, 10);
910     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
911     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
912
913     /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
914
915     memset(bits, 0, sizeof(bits));
916     bits[0] = 0xaa;
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     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
922
923     pbmi->bmiColors[0].rgbRed = 0x0;
924     pbmi->bmiColors[0].rgbGreen = 0x0;
925     pbmi->bmiColors[0].rgbBlue = 0x0;
926     pbmi->bmiColors[1].rgbRed = 0xff;
927     pbmi->bmiColors[1].rgbGreen = 0xff;
928     pbmi->bmiColors[1].rgbBlue = 0xff;
929
930     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
931     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
932
933     SelectObject(memdc, old_bm);
934     DeleteObject(mono_ds);
935
936     /*
937      * Next dib section is 'normal' ie color[0] is black, color[1] is white
938      */
939
940     pbmi->bmiColors[0].rgbRed = 0x0;
941     pbmi->bmiColors[0].rgbGreen = 0x0;
942     pbmi->bmiColors[0].rgbBlue = 0x0;
943     pbmi->bmiColors[1].rgbRed = 0xff;
944     pbmi->bmiColors[1].rgbGreen = 0xff;
945     pbmi->bmiColors[1].rgbBlue = 0xff;
946
947     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
948     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
949     old_bm = SelectObject(memdc, mono_ds);
950
951     /* black border, white interior */
952     Rectangle(memdc, 0, 0, 10, 10);
953     ok(ds_bits[0] == 0x00, "out_bits %02x\n", ds_bits[0]);
954     ok(ds_bits[4] == 0x7f, "out_bits %02x\n", ds_bits[4]);
955
956     /* SetDIBitsToDevice with a normal bmi -> normal dib section */
957
958     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
959     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
960
961     /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
962
963     pbmi->bmiColors[0].rgbRed = 0xff;
964     pbmi->bmiColors[0].rgbGreen = 0xff;
965     pbmi->bmiColors[0].rgbBlue = 0xff;
966     pbmi->bmiColors[1].rgbRed = 0x0;
967     pbmi->bmiColors[1].rgbGreen = 0x0;
968     pbmi->bmiColors[1].rgbBlue = 0x0;
969
970     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
971     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
972
973     /*
974      * Take that 'normal' dibsection and change its colour table to an 'inverted' one
975      */
976
977     pbmi->bmiColors[0].rgbRed = 0xff;
978     pbmi->bmiColors[0].rgbGreen = 0xff;
979     pbmi->bmiColors[0].rgbBlue = 0xff;
980     pbmi->bmiColors[1].rgbRed = 0x0;
981     pbmi->bmiColors[1].rgbGreen = 0x0;
982     pbmi->bmiColors[1].rgbBlue = 0x0;
983     num = SetDIBColorTable(memdc, 0, 2, pbmi->bmiColors);
984     ok(num == 2, "num = %d\n", num);
985
986     /* black border, white interior */
987     Rectangle(memdc, 0, 0, 10, 10);
988 todo_wine {
989     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
990     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
991  }
992     /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
993
994     memset(bits, 0, sizeof(bits));
995     bits[0] = 0xaa;
996
997     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
998     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
999
1000     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1001
1002     pbmi->bmiColors[0].rgbRed = 0x0;
1003     pbmi->bmiColors[0].rgbGreen = 0x0;
1004     pbmi->bmiColors[0].rgbBlue = 0x0;
1005     pbmi->bmiColors[1].rgbRed = 0xff;
1006     pbmi->bmiColors[1].rgbGreen = 0xff;
1007     pbmi->bmiColors[1].rgbBlue = 0xff;
1008
1009     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1010     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1011
1012     SelectObject(memdc, old_bm);
1013     DeleteObject(mono_ds);
1014
1015     /*
1016      * Now a dib section with a strange colour map just for fun.  This behaves just like an inverted one.
1017      */
1018  
1019     pbmi->bmiColors[0].rgbRed = 0xff;
1020     pbmi->bmiColors[0].rgbGreen = 0x0;
1021     pbmi->bmiColors[0].rgbBlue = 0x0;
1022     pbmi->bmiColors[1].rgbRed = 0xfe;
1023     pbmi->bmiColors[1].rgbGreen = 0x0;
1024     pbmi->bmiColors[1].rgbBlue = 0x0;
1025
1026     mono_ds = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&ds_bits, NULL, 0);
1027     ok(mono_ds != NULL, "CreateDIBSection rets NULL\n");
1028     old_bm = SelectObject(memdc, mono_ds);
1029
1030     /* black border, white interior */
1031     Rectangle(memdc, 0, 0, 10, 10);
1032     ok(ds_bits[0] == 0xff, "out_bits %02x\n", ds_bits[0]);
1033     ok(ds_bits[4] == 0x80, "out_bits %02x\n", ds_bits[4]);
1034
1035     /* SetDIBitsToDevice with a normal bmi -> inverted dib section */
1036
1037     pbmi->bmiColors[0].rgbRed = 0x0;
1038     pbmi->bmiColors[0].rgbGreen = 0x0;
1039     pbmi->bmiColors[0].rgbBlue = 0x0;
1040     pbmi->bmiColors[1].rgbRed = 0xff;
1041     pbmi->bmiColors[1].rgbGreen = 0xff;
1042     pbmi->bmiColors[1].rgbBlue = 0xff;
1043
1044     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1045     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
1046
1047     /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
1048
1049     pbmi->bmiColors[0].rgbRed = 0xff;
1050     pbmi->bmiColors[0].rgbGreen = 0xff;
1051     pbmi->bmiColors[0].rgbBlue = 0xff;
1052     pbmi->bmiColors[1].rgbRed = 0x0;
1053     pbmi->bmiColors[1].rgbGreen = 0x0;
1054     pbmi->bmiColors[1].rgbBlue = 0x0;
1055
1056     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
1057     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
1058
1059     SelectObject(memdc, old_bm);
1060     DeleteObject(mono_ds);
1061
1062     DeleteDC(memdc);
1063     ReleaseDC(0, hdc);
1064 }
1065
1066 static void test_bitmap(void)
1067 {
1068     char buf[256], buf_cmp[256];
1069     HBITMAP hbmp, hbmp_old;
1070     HDC hdc;
1071     BITMAP bm;
1072     BITMAP bma[2];
1073     INT ret;
1074
1075     hdc = CreateCompatibleDC(0);
1076     assert(hdc != 0);
1077
1078     SetLastError(0xdeadbeef);
1079     hbmp = CreateBitmap(0x7ffffff, 1, 1, 1, NULL);
1080     if (!hbmp)
1081     {
1082         ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1083            GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1084            "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1085     }
1086     else
1087         DeleteObject(hbmp);
1088
1089     SetLastError(0xdeadbeef);
1090     hbmp = CreateBitmap(0x7ffffff, 9, 1, 1, NULL);
1091     if (!hbmp)
1092     {
1093         ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY /* XP */ ||
1094            GetLastError() == ERROR_INVALID_PARAMETER /* Win2k */,
1095            "expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
1096     }
1097     else
1098         DeleteObject(hbmp);
1099
1100     SetLastError(0xdeadbeef);
1101     hbmp = CreateBitmap(0x7ffffff + 1, 1, 1, 1, NULL);
1102     ok(!hbmp || broken(hbmp != NULL /* Win9x */), "CreateBitmap should fail\n");
1103     if (!hbmp)
1104         ok(GetLastError() == ERROR_INVALID_PARAMETER,
1105            "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1106     else
1107         DeleteObject(hbmp);
1108
1109     hbmp = CreateBitmap(15, 15, 1, 1, NULL);
1110     assert(hbmp != NULL);
1111
1112     ret = GetObject(hbmp, sizeof(bm), &bm);
1113     ok(ret == sizeof(bm), "wrong size %d\n", ret);
1114
1115     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1116     ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1117     ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1118     ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1119     ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1120     ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1121     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1122
1123     assert(sizeof(buf) >= bm.bmWidthBytes * bm.bmHeight);
1124     assert(sizeof(buf) == sizeof(buf_cmp));
1125
1126     ret = GetBitmapBits(hbmp, 0, NULL);
1127     ok(ret == bm.bmWidthBytes * bm.bmHeight || broken(ret == 0 /* Win9x */),
1128         "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1129
1130     memset(buf_cmp, 0xAA, sizeof(buf_cmp));
1131     memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
1132
1133     memset(buf, 0xAA, sizeof(buf));
1134     ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1135     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1136     ok(!memcmp(buf, buf_cmp, sizeof(buf)) ||
1137        broken(memcmp(buf, buf_cmp, sizeof(buf))), /* win9x doesn't init the bitmap bits */
1138        "buffers do not match\n");
1139
1140     hbmp_old = SelectObject(hdc, hbmp);
1141
1142     ret = GetObject(hbmp, sizeof(bm), &bm);
1143     ok(ret == sizeof(bm), "wrong size %d\n", ret);
1144
1145     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
1146     ok(bm.bmWidth == 15, "wrong bm.bmWidth %d\n", bm.bmWidth);
1147     ok(bm.bmHeight == 15, "wrong bm.bmHeight %d\n", bm.bmHeight);
1148     ok(bm.bmWidthBytes == 2, "wrong bm.bmWidthBytes %d\n", bm.bmWidthBytes);
1149     ok(bm.bmPlanes == 1, "wrong bm.bmPlanes %d\n", bm.bmPlanes);
1150     ok(bm.bmBitsPixel == 1, "wrong bm.bmBitsPixel %d\n", bm.bmBitsPixel);
1151     ok(bm.bmBits == NULL, "wrong bm.bmBits %p\n", bm.bmBits);
1152
1153     memset(buf, 0xAA, sizeof(buf));
1154     ret = GetBitmapBits(hbmp, sizeof(buf), buf);
1155     ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
1156     ok(!memcmp(buf, buf_cmp, sizeof(buf)) ||
1157        broken(memcmp(buf, buf_cmp, sizeof(buf))), /* win9x doesn't init the bitmap bits */
1158        "buffers do not match\n");
1159
1160     hbmp_old = SelectObject(hdc, hbmp_old);
1161     ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
1162
1163     /* test various buffer sizes for GetObject */
1164     ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
1165     ok(ret == sizeof(*bma) || broken(ret == sizeof(*bma) * 2 /* Win9x */), "wrong size %d\n", ret);
1166
1167     ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
1168     ok(ret == 0 || broken(ret == sizeof(bm) / 2 /* Win9x */), "%d != 0\n", ret);
1169
1170     ret = GetObject(hbmp, 0, &bm);
1171     ok(ret == 0, "%d != 0\n", ret);
1172
1173     ret = GetObject(hbmp, 1, &bm);
1174     ok(ret == 0 || broken(ret == 1 /* Win9x */), "%d != 0\n", ret);
1175
1176     DeleteObject(hbmp);
1177     DeleteDC(hdc);
1178 }
1179
1180 static void test_bmBits(void)
1181 {
1182     BYTE bits[4];
1183     HBITMAP hbmp;
1184     BITMAP bmp;
1185
1186     memset(bits, 0, sizeof(bits));
1187     hbmp = CreateBitmap(2, 2, 1, 4, bits);
1188     ok(hbmp != NULL, "CreateBitmap failed\n");
1189
1190     memset(&bmp, 0xFF, sizeof(bmp));
1191     ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
1192        "GetObject failed or returned a wrong structure size\n");
1193     ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
1194
1195     DeleteObject(hbmp);
1196 }
1197
1198 static void test_GetDIBits_selected_DIB(UINT bpp)
1199 {
1200     HBITMAP dib;
1201     BITMAPINFO * info;
1202     BITMAPINFO * info2;
1203     void * bits;
1204     void * bits2;
1205     UINT dib_size;
1206     HDC dib_dc, dc;
1207     HBITMAP old_bmp;
1208     BOOL equalContents;
1209     UINT i;
1210     int res;
1211
1212     /* Create a DIB section with a color table */
1213
1214     info  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1215     info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + (1 << bpp) * sizeof(RGBQUAD));
1216     assert(info);
1217     assert(info2);
1218
1219     info->bmiHeader.biSize = sizeof(info->bmiHeader);
1220
1221     /* Choose width and height such that the row length (in bytes)
1222        is a multiple of 4 (makes things easier) */
1223     info->bmiHeader.biWidth = 32;
1224     info->bmiHeader.biHeight = 32;
1225     info->bmiHeader.biPlanes = 1;
1226     info->bmiHeader.biBitCount = bpp;
1227     info->bmiHeader.biCompression = BI_RGB;
1228
1229     for (i=0; i < (1u << bpp); i++)
1230     {
1231         BYTE c = i * (1 << (8 - bpp));
1232         info->bmiColors[i].rgbRed = c;
1233         info->bmiColors[i].rgbGreen = c;
1234         info->bmiColors[i].rgbBlue = c;
1235         info->bmiColors[i].rgbReserved = 0;
1236     }
1237
1238     dib = CreateDIBSection(NULL, info, DIB_RGB_COLORS, &bits, NULL, 0);
1239     assert(dib);
1240     dib_size = bpp * (info->bmiHeader.biWidth * info->bmiHeader.biHeight) / 8;
1241
1242     /* Set the bits of the DIB section */
1243     for (i=0; i < dib_size; i++)
1244     {
1245         ((BYTE *)bits)[i] = i % 256;
1246     }
1247
1248     /* Select the DIB into a DC */
1249     dib_dc = CreateCompatibleDC(NULL);
1250     old_bmp = SelectObject(dib_dc, dib);
1251     dc = CreateCompatibleDC(NULL);
1252     bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dib_size);
1253     assert(bits2);
1254
1255     /* Copy the DIB attributes but not the color table */
1256     memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1257
1258     res = GetDIBits(dc, dib, 0, info->bmiHeader.biHeight, bits2, info2, DIB_RGB_COLORS);
1259     ok(res, "GetDIBits failed\n");
1260
1261     /* Compare the color table and the bits */
1262     equalContents = TRUE;
1263     for (i=0; i < (1u << bpp); i++)
1264     {
1265         if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1266             || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1267             || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1268             || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1269         {
1270             equalContents = FALSE;
1271             break;
1272         }
1273     }
1274     ok(equalContents, "GetDIBits with DIB selected in DC: Invalid DIB color table\n");
1275
1276     equalContents = TRUE;
1277     for (i=0; i < dib_size / sizeof(DWORD); i++)
1278     {
1279         if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1280         {
1281             equalContents = FALSE;
1282             break;
1283         }
1284     }
1285     ok(equalContents, "GetDIBits with %d bpp DIB selected in DC: Invalid DIB bits\n",bpp);
1286
1287     HeapFree(GetProcessHeap(), 0, bits2);
1288     DeleteDC(dc);
1289
1290     SelectObject(dib_dc, old_bmp);
1291     DeleteDC(dib_dc);
1292     DeleteObject(dib);
1293
1294     HeapFree(GetProcessHeap(), 0, info2);
1295     HeapFree(GetProcessHeap(), 0, info);
1296 }
1297
1298 static void test_GetDIBits_selected_DDB(BOOL monochrome)
1299 {
1300     HBITMAP ddb;
1301     BITMAPINFO * info;
1302     BITMAPINFO * info2;
1303     void * bits;
1304     void * bits2;
1305     HDC ddb_dc, dc;
1306     HBITMAP old_bmp;
1307     BOOL equalContents;
1308     UINT width, height;
1309     UINT bpp;
1310     UINT i, j;
1311     int res;
1312
1313     width = height = 16;
1314
1315     /* Create a DDB (device-dependent bitmap) */
1316     if (monochrome)
1317     {
1318         bpp = 1;
1319         ddb = CreateBitmap(width, height, 1, 1, NULL);
1320     }
1321     else
1322     {
1323         HDC screen_dc = GetDC(NULL);
1324         bpp = GetDeviceCaps(screen_dc, BITSPIXEL) * GetDeviceCaps(screen_dc, PLANES);
1325         ddb = CreateCompatibleBitmap(screen_dc, width, height);
1326         ReleaseDC(NULL, screen_dc);
1327     }
1328
1329     /* Set the pixels */
1330     ddb_dc = CreateCompatibleDC(NULL);
1331     old_bmp = SelectObject(ddb_dc, ddb);
1332     for (i = 0; i < width; i++)
1333     {
1334         for (j=0; j < height; j++)
1335         {
1336             BYTE c = (i * width + j) % 256;
1337             SetPixelV(ddb_dc, i, j, RGB(c, c, c));
1338         }
1339     }
1340     SelectObject(ddb_dc, old_bmp);
1341
1342     info  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1343     info2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
1344     assert(info);
1345     assert(info2);
1346
1347     info->bmiHeader.biSize = sizeof(info->bmiHeader);
1348     info->bmiHeader.biWidth = width;
1349     info->bmiHeader.biHeight = height;
1350     info->bmiHeader.biPlanes = 1;
1351     info->bmiHeader.biBitCount = bpp;
1352     info->bmiHeader.biCompression = BI_RGB;
1353
1354     dc = CreateCompatibleDC(NULL);
1355
1356     /* Fill in biSizeImage */
1357     GetDIBits(dc, ddb, 0, height, NULL, info, DIB_RGB_COLORS);
1358     ok(info->bmiHeader.biSizeImage != 0, "GetDIBits failed to get the DIB attributes\n");
1359
1360     bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1361     bits2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage);
1362     assert(bits);
1363     assert(bits2);
1364
1365     /* Get the bits */
1366     res = GetDIBits(dc, ddb, 0, height, bits, info, DIB_RGB_COLORS);
1367     ok(res, "GetDIBits failed\n");
1368
1369     /* Copy the DIB attributes but not the color table */
1370     memcpy(info2, info, sizeof(BITMAPINFOHEADER));
1371
1372     /* Select the DDB into another DC */
1373     old_bmp = SelectObject(ddb_dc, ddb);
1374
1375     /* Get the bits */
1376     res = GetDIBits(dc, ddb, 0, height, bits2, info2, DIB_RGB_COLORS);
1377     ok(res, "GetDIBits failed\n");
1378
1379     /* Compare the color table and the bits */
1380     if (bpp <= 8)
1381     {
1382         equalContents = TRUE;
1383         for (i=0; i < (1u << bpp); i++)
1384         {
1385             if ((info->bmiColors[i].rgbRed != info2->bmiColors[i].rgbRed)
1386                 || (info->bmiColors[i].rgbGreen != info2->bmiColors[i].rgbGreen)
1387                 || (info->bmiColors[i].rgbBlue != info2->bmiColors[i].rgbBlue)
1388                 || (info->bmiColors[i].rgbReserved != info2->bmiColors[i].rgbReserved))
1389             {
1390                 equalContents = FALSE;
1391                 break;
1392             }
1393         }
1394         ok(equalContents, "GetDIBits with DDB selected in DC: Got a different color table\n");
1395     }
1396
1397     equalContents = TRUE;
1398     for (i=0; i < info->bmiHeader.biSizeImage / sizeof(DWORD); i++)
1399     {
1400         if (((DWORD *)bits)[i] != ((DWORD *)bits2)[i])
1401         {
1402             equalContents = FALSE;
1403         }
1404     }
1405     ok(equalContents, "GetDIBits with DDB selected in DC: Got different DIB bits\n");
1406
1407     /* Test the palette */
1408     equalContents = TRUE;
1409     if (info2->bmiHeader.biBitCount <= 8)
1410     {
1411         WORD *colors = (WORD*)info2->bmiColors;
1412
1413         /* Get the palette indices */
1414         res = GetDIBits(dc, ddb, 0, 0, NULL, info2, DIB_PAL_COLORS);
1415         if (res == 0 && GetLastError() == ERROR_INVALID_PARAMETER) /* Win9x */
1416             res = GetDIBits(dc, ddb, 0, height, NULL, info2, DIB_PAL_COLORS);
1417         ok(res, "GetDIBits failed\n");
1418
1419         for (i=0;i < 1 << info->bmiHeader.biSizeImage; i++)
1420         {
1421             if (colors[i] != i)
1422             {
1423                 equalContents = FALSE;
1424                 break;
1425             }
1426         }
1427     }
1428
1429     ok(equalContents, "GetDIBits with DDB selected in DC: non 1:1 palette indices\n");
1430
1431     HeapFree(GetProcessHeap(), 0, bits2);
1432     HeapFree(GetProcessHeap(), 0, bits);
1433     DeleteDC(dc);
1434
1435     SelectObject(ddb_dc, old_bmp);
1436     DeleteDC(ddb_dc);
1437     DeleteObject(ddb);
1438
1439     HeapFree(GetProcessHeap(), 0, info2);
1440     HeapFree(GetProcessHeap(), 0, info);
1441 }
1442
1443 static void test_GetDIBits(void)
1444 {
1445     /* 2-bytes aligned 1-bit bitmap data: 16x16 */
1446     static const BYTE bmp_bits_1[16 * 2] =
1447     {
1448         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1449         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1450         0xff,0xff, 0,0, 0xff,0xff, 0,0,
1451         0xff,0xff, 0,0, 0xff,0xff, 0,0
1452     };
1453     /* 4-bytes aligned 1-bit DIB data: 16x16 */
1454     static const BYTE dib_bits_1[16 * 4] =
1455     {
1456         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1457         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1458         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0,
1459         0,0,0,0, 0xff,0xff,0,0, 0,0,0,0, 0xff,0xff,0,0
1460     };
1461     static const BYTE dib_bits_1_9x[16 * 4] =
1462     {
1463         0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa, 0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa,
1464         0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa, 0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa,
1465         0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa, 0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa,
1466         0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa, 0,0,0xaa,0xaa, 0xff,0xff,0xaa,0xaa
1467     };
1468     /* 2-bytes aligned 24-bit bitmap data: 16x16 */
1469     static const BYTE bmp_bits_24[16 * 16*3] =
1470     {
1471         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1472         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1473         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1474         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1475         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1476         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1477         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1478         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1479         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1480         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1481         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1482         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1483         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1484         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1485         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1486         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1487         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1488         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1489         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1490         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1491         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1492         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1493         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1494         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1495         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1496         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1497         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1498         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1499         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1500         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1501         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1502         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1503     };
1504     /* 4-bytes aligned 24-bit DIB data: 16x16 */
1505     static const BYTE dib_bits_24[16 * 16*3] =
1506     {
1507         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1508         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1509         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1510         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1511         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1512         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1513         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1514         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1515         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1516         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1517         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1518         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1519         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1520         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1521         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1522         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1523         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1524         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1525         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1526         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1527         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1528         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1529         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1530         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1531         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1532         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1533         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1534         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1535         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1536         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1537         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1538         0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1539     };
1540     HBITMAP hbmp;
1541     BITMAP bm;
1542     HDC hdc;
1543     int i, bytes, lines;
1544     BYTE buf[1024];
1545     char bi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
1546     BITMAPINFO *bi = (BITMAPINFO *)bi_buf;
1547
1548     hdc = GetDC(0);
1549
1550     /* 1-bit source bitmap data */
1551     hbmp = CreateBitmap(16, 16, 1, 1, bmp_bits_1);
1552     ok(hbmp != 0, "CreateBitmap failed\n");
1553
1554     memset(&bm, 0xAA, sizeof(bm));
1555     bytes = GetObject(hbmp, sizeof(bm), &bm);
1556     ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1557     ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
1558     ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1559     ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1560     ok(bm.bmWidthBytes == 2, "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1561     ok(bm.bmPlanes == 1, "wrong bmPlanes %u\n", bm.bmPlanes);
1562     ok(bm.bmBitsPixel == 1, "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1563     ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1564
1565     bytes = GetBitmapBits(hbmp, 0, NULL);
1566     ok(bytes == sizeof(bmp_bits_1) || broken(bytes == 0 /* Win9x */), "expected 16*2 got %d bytes\n", bytes);
1567     bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1568     ok(bytes == sizeof(bmp_bits_1), "expected 16*2 got %d bytes\n", bytes);
1569     ok(!memcmp(buf, bmp_bits_1, sizeof(bmp_bits_1)), "bitmap bits don't match\n");
1570
1571     /* retrieve 1-bit DIB data */
1572     memset(bi, 0, sizeof(*bi));
1573     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1574     bi->bmiHeader.biWidth = bm.bmWidth;
1575     bi->bmiHeader.biHeight = bm.bmHeight;
1576     bi->bmiHeader.biPlanes = 1;
1577     bi->bmiHeader.biBitCount = 1;
1578     bi->bmiHeader.biCompression = BI_RGB;
1579     bi->bmiHeader.biSizeImage = 0;
1580     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1581     SetLastError(0xdeadbeef);
1582     lines = GetDIBits(0, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1583     ok(lines == 0, "GetDIBits copied %d lines with hdc = 0\n", lines);
1584     ok(GetLastError() == ERROR_INVALID_PARAMETER ||
1585        broken(GetLastError() == 0xdeadbeef), /* winnt */
1586        "wrong error %u\n", GetLastError());
1587     ok(bi->bmiHeader.biSizeImage == 0, "expected 0, got %u\n", bi->bmiHeader.biSizeImage);
1588
1589     memset(buf, 0xAA, sizeof(buf));
1590     SetLastError(0xdeadbeef);
1591     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1592     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1593        lines, bm.bmHeight, GetLastError());
1594     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1) ||
1595        broken(bi->bmiHeader.biSizeImage == 0), /* win9x */
1596        "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1597
1598     /* the color table consists of black and white */
1599     ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1600        bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1601        "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1602        bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1603        bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1604     ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1605        bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1606        "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1607        bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1608        bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1609     for (i = 2; i < 256; i++)
1610     {
1611         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1612            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1613            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1614            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1615            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1616     }
1617
1618     /* returned bits are DWORD aligned and upside down */
1619     ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)) ||
1620        broken(!memcmp(buf, dib_bits_1_9x, sizeof(dib_bits_1_9x))), /* Win9x, WinME */
1621        "DIB bits don't match\n");
1622
1623     /* Test the palette indices */
1624     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1625     SetLastError(0xdeadbeef);
1626     lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1627     if (lines == 0 && GetLastError() == ERROR_INVALID_PARAMETER)
1628         win_skip("Win9x/WinMe doesn't handle 0 for the number of scan lines\n");
1629     else
1630     {
1631         ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1632         ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1633     }
1634     for (i = 2; i < 256; i++)
1635         ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[1]);
1636
1637     /* retrieve 24-bit DIB data */
1638     memset(bi, 0, sizeof(*bi));
1639     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1640     bi->bmiHeader.biWidth = bm.bmWidth;
1641     bi->bmiHeader.biHeight = bm.bmHeight;
1642     bi->bmiHeader.biPlanes = 1;
1643     bi->bmiHeader.biBitCount = 24;
1644     bi->bmiHeader.biCompression = BI_RGB;
1645     bi->bmiHeader.biSizeImage = 0;
1646     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1647     memset(buf, 0xAA, sizeof(buf));
1648     SetLastError(0xdeadbeef);
1649     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1650     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1651        lines, bm.bmHeight, GetLastError());
1652     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24) ||
1653        broken(bi->bmiHeader.biSizeImage == 0), /* win9x */
1654        "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1655
1656     /* the color table doesn't exist for 24-bit images */
1657     for (i = 0; i < 256; i++)
1658     {
1659         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1660            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1661            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1662            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1663            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1664     }
1665
1666     /* returned bits are DWORD aligned and upside down */
1667     ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1668     DeleteObject(hbmp);
1669
1670     /* 24-bit source bitmap data */
1671     hbmp = CreateCompatibleBitmap(hdc, 16, 16);
1672     ok(hbmp != 0, "CreateBitmap failed\n");
1673     SetLastError(0xdeadbeef);
1674     bi->bmiHeader.biHeight = -bm.bmHeight; /* indicate bottom-up data */
1675     lines = SetDIBits(hdc, hbmp, 0, bm.bmHeight, bmp_bits_24, bi, DIB_RGB_COLORS);
1676     ok(lines == bm.bmHeight, "SetDIBits copied %d lines of %d, error %u\n",
1677        lines, bm.bmHeight, GetLastError());
1678
1679     memset(&bm, 0xAA, sizeof(bm));
1680     bytes = GetObject(hbmp, sizeof(bm), &bm);
1681     ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1682     ok(bm.bmType == 0 ||
1683        broken(bm.bmType == 21072), /* win9x */
1684        "wrong bmType %d\n", bm.bmType);
1685     ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
1686     ok(bm.bmHeight == 16, "wrong bmHeight %d\n", bm.bmHeight);
1687     ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1688     ok(bm.bmPlanes == GetDeviceCaps(hdc, PLANES), "wrong bmPlanes %u\n", bm.bmPlanes);
1689     ok(bm.bmBitsPixel == GetDeviceCaps(hdc, BITSPIXEL), "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1690     ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1691
1692     bytes = GetBitmapBits(hbmp, 0, NULL);
1693     ok(bytes == bm.bmWidthBytes * bm.bmHeight ||
1694        broken(bytes == 0), /* win9x */
1695        "expected %d got %d bytes\n", bm.bmWidthBytes * bm.bmHeight, bytes);
1696     bytes = GetBitmapBits(hbmp, sizeof(buf), buf);
1697     ok(bytes == bm.bmWidthBytes * bm.bmHeight, "expected %d got %d bytes\n",
1698        bm.bmWidthBytes * bm.bmHeight, bytes);
1699
1700     /* retrieve 1-bit DIB data */
1701     memset(bi, 0, sizeof(*bi));
1702     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1703     bi->bmiHeader.biWidth = bm.bmWidth;
1704     bi->bmiHeader.biHeight = bm.bmHeight;
1705     bi->bmiHeader.biPlanes = 1;
1706     bi->bmiHeader.biBitCount = 1;
1707     bi->bmiHeader.biCompression = BI_RGB;
1708     bi->bmiHeader.biSizeImage = 0;
1709     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1710     memset(buf, 0xAA, sizeof(buf));
1711     SetLastError(0xdeadbeef);
1712     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1713     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1714        lines, bm.bmHeight, GetLastError());
1715     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_1) ||
1716        broken(bi->bmiHeader.biSizeImage == 0), /* win9x */
1717        "expected 16*4, got %u\n", bi->bmiHeader.biSizeImage);
1718
1719     /* the color table consists of black and white */
1720     ok(bi->bmiColors[0].rgbRed == 0 && bi->bmiColors[0].rgbGreen == 0 &&
1721        bi->bmiColors[0].rgbBlue == 0 && bi->bmiColors[0].rgbReserved == 0,
1722        "expected bmiColors[0] 0,0,0,0 - got %x %x %x %x\n",
1723        bi->bmiColors[0].rgbRed, bi->bmiColors[0].rgbGreen,
1724        bi->bmiColors[0].rgbBlue, bi->bmiColors[0].rgbReserved);
1725     ok(bi->bmiColors[1].rgbRed == 0xff && bi->bmiColors[1].rgbGreen == 0xff &&
1726        bi->bmiColors[1].rgbBlue == 0xff && bi->bmiColors[1].rgbReserved == 0,
1727        "expected bmiColors[0] 0xff,0xff,0xff,0 - got %x %x %x %x\n",
1728        bi->bmiColors[1].rgbRed, bi->bmiColors[1].rgbGreen,
1729        bi->bmiColors[1].rgbBlue, bi->bmiColors[1].rgbReserved);
1730     for (i = 2; i < 256; i++)
1731     {
1732         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1733            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1734            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1735            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1736            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1737     }
1738
1739     /* returned bits are DWORD aligned and upside down */
1740 todo_wine
1741     ok(!memcmp(buf, dib_bits_1, sizeof(dib_bits_1)) ||
1742        broken(!memcmp(buf, dib_bits_1_9x, sizeof(dib_bits_1_9x))), /* Win9x, WinME */
1743        "DIB bits don't match\n");
1744
1745     /* Test the palette indices */
1746     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1747     SetLastError(0xdeadbeef);
1748     lines = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS);
1749     if (lines == 0 && GetLastError() == ERROR_INVALID_PARAMETER)
1750         win_skip("Win9x/WinMe doesn't handle 0 for the number of scan lines\n");
1751     else
1752     {
1753         ok(((WORD*)bi->bmiColors)[0] == 0, "Color 0 is %d\n", ((WORD*)bi->bmiColors)[0]);
1754         ok(((WORD*)bi->bmiColors)[1] == 1, "Color 1 is %d\n", ((WORD*)bi->bmiColors)[1]);
1755     }
1756     for (i = 2; i < 256; i++)
1757         ok(((WORD*)bi->bmiColors)[i] == 0xAAAA, "Color %d is %d\n", i, ((WORD*)bi->bmiColors)[i]);
1758
1759     /* retrieve 24-bit DIB data */
1760     memset(bi, 0, sizeof(*bi));
1761     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1762     bi->bmiHeader.biWidth = bm.bmWidth;
1763     bi->bmiHeader.biHeight = bm.bmHeight;
1764     bi->bmiHeader.biPlanes = 1;
1765     bi->bmiHeader.biBitCount = 24;
1766     bi->bmiHeader.biCompression = BI_RGB;
1767     bi->bmiHeader.biSizeImage = 0;
1768     memset(bi->bmiColors, 0xAA, sizeof(RGBQUAD) * 256);
1769     memset(buf, 0xAA, sizeof(buf));
1770     SetLastError(0xdeadbeef);
1771     lines = GetDIBits(hdc, hbmp, 0, bm.bmHeight, buf, bi, DIB_RGB_COLORS);
1772     ok(lines == bm.bmHeight, "GetDIBits copied %d lines of %d, error %u\n",
1773        lines, bm.bmHeight, GetLastError());
1774     ok(bi->bmiHeader.biSizeImage == sizeof(dib_bits_24) ||
1775        broken(bi->bmiHeader.biSizeImage == 0), /* win9x */
1776        "expected 16*16*3, got %u\n", bi->bmiHeader.biSizeImage);
1777
1778     /* the color table doesn't exist for 24-bit images */
1779     for (i = 0; i < 256; i++)
1780     {
1781         ok(bi->bmiColors[i].rgbRed == 0xAA && bi->bmiColors[i].rgbGreen == 0xAA &&
1782            bi->bmiColors[i].rgbBlue == 0xAA && bi->bmiColors[i].rgbReserved == 0xAA,
1783            "expected bmiColors[%d] 0xAA,0xAA,0xAA,0xAA - got %x %x %x %x\n", i,
1784            bi->bmiColors[i].rgbRed, bi->bmiColors[i].rgbGreen,
1785            bi->bmiColors[i].rgbBlue, bi->bmiColors[i].rgbReserved);
1786     }
1787
1788     /* returned bits are DWORD aligned and upside down */
1789     ok(!memcmp(buf, dib_bits_24, sizeof(dib_bits_24)), "DIB bits don't match\n");
1790     DeleteObject(hbmp);
1791
1792     ReleaseDC(0, hdc);
1793 }
1794
1795 static void test_GetDIBits_BI_BITFIELDS(void)
1796 {
1797     /* Try a screen resolution detection technique
1798      * from the September 1999 issue of Windows Developer's Journal
1799      * which seems to be in widespread use.
1800      * http://www.lesher.ws/highcolor.html
1801      * http://www.lesher.ws/vidfmt.c
1802      * It hinges on being able to retrieve the bitmaps
1803      * for the three primary colors in non-paletted 16 bit mode.
1804      */
1805     char dibinfo_buf[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
1806     DWORD bits[32];
1807     LPBITMAPINFO dibinfo = (LPBITMAPINFO) dibinfo_buf;
1808     HDC hdc;
1809     HBITMAP hbm;
1810     int ret;
1811
1812     memset(dibinfo, 0, sizeof(dibinfo_buf));
1813     dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1814
1815     hdc = GetDC(NULL);
1816     ok(hdc != NULL, "GetDC failed?\n");
1817     hbm = CreateCompatibleBitmap(hdc, 1, 1);
1818     ok(hbm != NULL, "CreateCompatibleBitmap failed?\n");
1819
1820     /* Call GetDIBits to fill in bmiHeader.  */
1821     ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1822     ok(ret == 1, "GetDIBits failed\n");
1823     if (dibinfo->bmiHeader.biBitCount > 8)
1824     {
1825         DWORD *bitmasks = (DWORD *)dibinfo->bmiColors;
1826
1827         ok( dibinfo->bmiHeader.biCompression == BI_BITFIELDS,
1828             "compression is %u\n", dibinfo->bmiHeader.biCompression );
1829
1830         ok( !bitmasks[0], "red mask is set\n" );
1831         ok( !bitmasks[1], "green mask is set\n" );
1832         ok( !bitmasks[2], "blue mask is set\n" );
1833
1834         /* test with NULL bits pointer and correct bpp */
1835         dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1836         ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1837         ok(ret == 1, "GetDIBits failed\n");
1838
1839         ok( bitmasks[0] != 0, "red mask is not set\n" );
1840         ok( bitmasks[1] != 0, "green mask is not set\n" );
1841         ok( bitmasks[2] != 0, "blue mask is not set\n" );
1842         ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1843
1844         /* test with valid bits pointer */
1845         memset(dibinfo, 0, sizeof(dibinfo_buf));
1846         dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1847         ret = GetDIBits(hdc, hbm, 0, 1, NULL, dibinfo, DIB_RGB_COLORS);
1848         ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1849         dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1850         ret = GetDIBits(hdc, hbm, 0, 1, bits, dibinfo, DIB_RGB_COLORS);
1851         ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1852
1853         ok( bitmasks[0] != 0, "red mask is not set\n" );
1854         ok( bitmasks[1] != 0, "green mask is not set\n" );
1855         ok( bitmasks[2] != 0, "blue mask is not set\n" );
1856         ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef ||
1857             broken(dibinfo->bmiHeader.biSizeImage == 0xdeadbeef), /* win9x */
1858             "size image not set\n" );
1859
1860         /* now with bits and 0 lines */
1861         memset(dibinfo, 0, sizeof(dibinfo_buf));
1862         dibinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1863         dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1864         SetLastError(0xdeadbeef);
1865         ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
1866         if (ret == 0 && GetLastError() == ERROR_INVALID_PARAMETER)
1867             win_skip("Win9x/WinMe doesn't handle 0 for the number of scan lines\n");
1868         else
1869         {
1870             ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1871
1872             ok( !bitmasks[0], "red mask is set\n" );
1873             ok( !bitmasks[1], "green mask is set\n" );
1874             ok( !bitmasks[2], "blue mask is set\n" );
1875             ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1876
1877             memset(bitmasks, 0, 3*sizeof(DWORD));
1878             dibinfo->bmiHeader.biSizeImage = 0xdeadbeef;
1879             ret = GetDIBits(hdc, hbm, 0, 0, bits, dibinfo, DIB_RGB_COLORS);
1880             ok(ret == 1, "GetDIBits failed ret %u err %u\n",ret,GetLastError());
1881
1882             ok( bitmasks[0] != 0, "red mask is not set\n" );
1883             ok( bitmasks[1] != 0, "green mask is not set\n" );
1884             ok( bitmasks[2] != 0, "blue mask is not set\n" );
1885             ok( dibinfo->bmiHeader.biSizeImage != 0xdeadbeef, "size image not set\n" );
1886         }
1887     }
1888     else skip("not in 16 bpp BI_BITFIELDS mode, skipping that test\n");
1889
1890     DeleteObject(hbm);
1891     ReleaseDC(NULL, hdc);
1892 }
1893
1894 static void test_select_object(void)
1895 {
1896     HDC hdc;
1897     HBITMAP hbm, hbm_old;
1898     INT planes, bpp, i;
1899     DWORD depths[] = {8, 15, 16, 24, 32};
1900     BITMAP bm;
1901     DWORD bytes;
1902
1903     hdc = GetDC(0);
1904     ok(hdc != 0, "GetDC(0) failed\n");
1905     hbm = CreateCompatibleBitmap(hdc, 10, 10);
1906     ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1907
1908     hbm_old = SelectObject(hdc, hbm);
1909     ok(hbm_old == 0, "SelectObject should fail\n");
1910
1911     DeleteObject(hbm);
1912     ReleaseDC(0, hdc);
1913
1914     hdc = CreateCompatibleDC(0);
1915     ok(hdc != 0, "GetDC(0) failed\n");
1916     hbm = CreateCompatibleBitmap(hdc, 10, 10);
1917     ok(hbm != 0, "CreateCompatibleBitmap failed\n");
1918
1919     hbm_old = SelectObject(hdc, hbm);
1920     ok(hbm_old != 0, "SelectObject failed\n");
1921     hbm_old = SelectObject(hdc, hbm_old);
1922     ok(hbm_old == hbm, "SelectObject failed\n");
1923
1924     DeleteObject(hbm);
1925
1926     /* test an 1-bpp bitmap */
1927     planes = GetDeviceCaps(hdc, PLANES);
1928     bpp = 1;
1929
1930     hbm = CreateBitmap(10, 10, planes, bpp, NULL);
1931     ok(hbm != 0, "CreateBitmap failed\n");
1932
1933     hbm_old = SelectObject(hdc, hbm);
1934     ok(hbm_old != 0, "SelectObject failed\n");
1935     hbm_old = SelectObject(hdc, hbm_old);
1936     ok(hbm_old == hbm, "SelectObject failed\n");
1937
1938     DeleteObject(hbm);
1939
1940     for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
1941         /* test a color bitmap to dc bpp matching */
1942         planes = GetDeviceCaps(hdc, PLANES);
1943         bpp = GetDeviceCaps(hdc, BITSPIXEL);
1944
1945         hbm = CreateBitmap(10, 10, planes, depths[i], NULL);
1946         ok(hbm != 0, "CreateBitmap failed\n");
1947
1948         hbm_old = SelectObject(hdc, hbm);
1949         if(depths[i] == bpp ||
1950           (bpp == 16 && depths[i] == 15)        /* 16 and 15 bpp are compatible */
1951           ) {
1952             ok(hbm_old != 0, "SelectObject failed, BITSPIXEL: %d, created depth: %d\n", bpp, depths[i]);
1953             SelectObject(hdc, hbm_old);
1954         } else {
1955             ok(hbm_old == 0, "SelectObject should fail. BITSPIXELS: %d, created depth: %d\n", bpp, depths[i]);
1956         }
1957
1958         memset(&bm, 0xAA, sizeof(bm));
1959         bytes = GetObject(hbm, sizeof(bm), &bm);
1960         ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
1961         ok(bm.bmType == 0 ||
1962            broken(bm.bmType == 21072), /* win9x */
1963            "wrong bmType %d\n", bm.bmType);
1964         ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
1965         ok(bm.bmHeight == 10, "wrong bmHeight %d\n", bm.bmHeight);
1966         ok(bm.bmWidthBytes == BITMAP_GetWidthBytes(bm.bmWidth, bm.bmBitsPixel), "wrong bmWidthBytes %d\n", bm.bmWidthBytes);
1967         ok(bm.bmPlanes == planes, "wrong bmPlanes %u\n", bm.bmPlanes);
1968         if(depths[i] == 15) {
1969             ok(bm.bmBitsPixel == 16 ||
1970                broken(bm.bmBitsPixel == 15), /* Win9x/WinME */
1971                "wrong bmBitsPixel %d(15 bpp special)\n", bm.bmBitsPixel);
1972         } else {
1973             ok(bm.bmBitsPixel == depths[i], "wrong bmBitsPixel %d\n", bm.bmBitsPixel);
1974         }
1975         ok(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
1976
1977         DeleteObject(hbm);
1978     }
1979
1980     DeleteDC(hdc);
1981 }
1982
1983 static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
1984 {
1985     INT ret;
1986     BITMAP bm;
1987
1988     ret = GetObjectType(hbmp);
1989     ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
1990
1991     ret = GetObject(hbmp, 0, 0);
1992     ok_(__FILE__, line)(ret == sizeof(BITMAP) /* XP */ ||
1993                         ret == sizeof(DIBSECTION) /* Win9x */, "object size %d\n", ret);
1994
1995     memset(&bm, 0xDA, sizeof(bm));
1996     SetLastError(0xdeadbeef);
1997     ret = GetObject(hbmp, sizeof(bm), &bm);
1998     if (!ret) /* XP, only for curObj2 */ return;
1999     ok_(__FILE__, line)(ret == sizeof(BITMAP) ||
2000                         ret == sizeof(DIBSECTION) /* Win9x, only for curObj2 */,
2001                         "GetObject returned %d, error %u\n", ret, GetLastError());
2002     ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
2003     ok_(__FILE__, line)(bm.bmWidth == 1, "wrong bmWidth, expected 1 got %d\n", bm.bmWidth);
2004     ok_(__FILE__, line)(bm.bmHeight == 1, "wrong bmHeight, expected 1 got %d\n", bm.bmHeight);
2005     ok_(__FILE__, line)(bm.bmWidthBytes == 2, "wrong bmWidthBytes, expected 2 got %d\n", bm.bmWidthBytes);
2006     ok_(__FILE__, line)(bm.bmPlanes == 1, "wrong bmPlanes, expected 1 got %u\n", bm.bmPlanes);
2007     ok_(__FILE__, line)(bm.bmBitsPixel == 1, "wrong bmBitsPixel, expected 1 got %d\n", bm.bmBitsPixel);
2008     ok_(__FILE__, line)(!bm.bmBits, "wrong bmBits %p\n", bm.bmBits);
2009 }
2010
2011 #define test_mono_1x1_bmp(a) test_mono_1x1_bmp_dbg((a), __LINE__)
2012
2013 static void test_CreateBitmap(void)
2014 {
2015     BITMAP bmp;
2016     HDC screenDC = GetDC(0);
2017     HDC hdc = CreateCompatibleDC(screenDC);
2018     UINT i, expect = 0;
2019
2020     /* all of these are the stock monochrome bitmap */
2021     HBITMAP bm = CreateCompatibleBitmap(hdc, 0, 0);
2022     HBITMAP bm1 = CreateCompatibleBitmap(screenDC, 0, 0);
2023     HBITMAP bm4 = CreateBitmap(0, 1, 0, 0, 0);
2024     HBITMAP bm5 = CreateDiscardableBitmap(hdc, 0, 0);
2025     HBITMAP curObj1 = GetCurrentObject(hdc, OBJ_BITMAP);
2026     HBITMAP curObj2 = GetCurrentObject(screenDC, OBJ_BITMAP);
2027
2028     /* these 2 are not the stock monochrome bitmap */
2029     HBITMAP bm2 = CreateCompatibleBitmap(hdc, 1, 1);
2030     HBITMAP bm3 = CreateBitmap(1, 1, 1, 1, 0);
2031
2032     HBITMAP old1 = SelectObject(hdc, bm2);
2033     HBITMAP old2 = SelectObject(screenDC, bm3);
2034     SelectObject(hdc, old1);
2035     SelectObject(screenDC, old2);
2036
2037     ok(bm == bm1 && bm == bm4 && bm == bm5 && bm == curObj1 && bm == old1,
2038        "0: %p, 1: %p, 4: %p, 5: %p, curObj1 %p, old1 %p\n",
2039        bm, bm1, bm4, bm5, curObj1, old1);
2040     ok(bm != bm2 && bm != bm3, "0: %p, 2: %p, 3: %p\n", bm, bm2, bm3);
2041 todo_wine
2042     ok(bm != curObj2 || /* WinXP */
2043        broken(bm == curObj2) /* Win9x */,
2044        "0: %p, curObj2 %p\n", bm, curObj2);
2045     ok(old2 == 0, "old2 %p\n", old2);
2046
2047     test_mono_1x1_bmp(bm);
2048     test_mono_1x1_bmp(bm1);
2049     test_mono_1x1_bmp(bm2);
2050     test_mono_1x1_bmp(bm3);
2051     test_mono_1x1_bmp(bm4);
2052     test_mono_1x1_bmp(bm5);
2053     test_mono_1x1_bmp(old1);
2054     test_mono_1x1_bmp(curObj1);
2055
2056     DeleteObject(bm);
2057     DeleteObject(bm1);
2058     DeleteObject(bm2);
2059     DeleteObject(bm3);
2060     DeleteObject(bm4);
2061     DeleteObject(bm5);
2062
2063     DeleteDC(hdc);
2064     ReleaseDC(0, screenDC);
2065
2066     /* show that Windows ignores the provided bm.bmWidthBytes */
2067     bmp.bmType = 0;
2068     bmp.bmWidth = 1;
2069     bmp.bmHeight = 1;
2070     bmp.bmWidthBytes = 28;
2071     bmp.bmPlanes = 1;
2072     bmp.bmBitsPixel = 1;
2073     bmp.bmBits = NULL;
2074     bm = CreateBitmapIndirect(&bmp);
2075     ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2076     test_mono_1x1_bmp(bm);
2077     DeleteObject(bm);
2078
2079     /* Test how the bmBitsPixel field is treated */
2080     for(i = 1; i <= 33; i++) {
2081         bmp.bmType = 0;
2082         bmp.bmWidth = 1;
2083         bmp.bmHeight = 1;
2084         bmp.bmWidthBytes = 28;
2085         bmp.bmPlanes = 1;
2086         bmp.bmBitsPixel = i;
2087         bmp.bmBits = NULL;
2088         SetLastError(0xdeadbeef);
2089         bm = CreateBitmapIndirect(&bmp);
2090         if(i > 32) {
2091             DWORD error = GetLastError();
2092             ok(bm == 0 ||
2093                broken(bm != 0), /* Win9x and WinMe */
2094                "CreateBitmapIndirect for %d bpp succeeded\n", i);
2095             ok(error == ERROR_INVALID_PARAMETER ||
2096                broken(error == 0xdeadbeef), /* Win9x and WinME */
2097                "Got error %d, expected ERROR_INVALID_PARAMETER\n", error);
2098             DeleteObject(bm);
2099             continue;
2100         }
2101         ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
2102         GetObject(bm, sizeof(bmp), &bmp);
2103         if(i == 1) {
2104             expect = 1;
2105         } else if(i <= 4) {
2106             expect = 4;
2107         } else if(i <= 8) {
2108             expect = 8;
2109         } else if(i <= 16) {
2110             expect = 16;
2111         } else if(i <= 24) {
2112             expect = 24;
2113         } else if(i <= 32) {
2114             expect = 32;
2115         }
2116         ok(bmp.bmBitsPixel == expect ||
2117            broken(bmp.bmBitsPixel == i), /* Win9x and WinMe */
2118            "CreateBitmapIndirect for a %d bpp bitmap created a %d bpp bitmap, expected %d\n",
2119            i, bmp.bmBitsPixel, expect);
2120         DeleteObject(bm);
2121     }
2122 }
2123
2124 static void test_bitmapinfoheadersize(void)
2125 {
2126     HBITMAP hdib;
2127     BITMAPINFO bmi;
2128     BITMAPCOREINFO bci;
2129     HDC hdc = GetDC(0);
2130
2131     memset(&bmi, 0, sizeof(BITMAPINFO));
2132     bmi.bmiHeader.biHeight = 100;
2133     bmi.bmiHeader.biWidth = 512;
2134     bmi.bmiHeader.biBitCount = 24;
2135     bmi.bmiHeader.biPlanes = 1;
2136
2137     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) - 1;
2138
2139     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2140     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2141
2142     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2143
2144     SetLastError(0xdeadbeef);
2145     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2146     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2147     DeleteObject(hdib);
2148
2149     bmi.bmiHeader.biSize++;
2150
2151     SetLastError(0xdeadbeef);
2152     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2153     ok(hdib != NULL ||
2154        broken(!hdib), /* Win98, WinMe */
2155        "CreateDIBSection error %d\n", GetLastError());
2156     DeleteObject(hdib);
2157
2158     bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
2159
2160     SetLastError(0xdeadbeef);
2161     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2162     ok(hdib != NULL ||
2163        broken(!hdib), /* Win98, WinMe */
2164        "CreateDIBSection error %d\n", GetLastError());
2165     DeleteObject(hdib);
2166
2167     bmi.bmiHeader.biSize++;
2168
2169     SetLastError(0xdeadbeef);
2170     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2171     ok(hdib != NULL ||
2172        broken(!hdib), /* Win98, WinMe */
2173        "CreateDIBSection error %d\n", GetLastError());
2174     DeleteObject(hdib);
2175
2176     bmi.bmiHeader.biSize = sizeof(BITMAPV4HEADER);
2177
2178     SetLastError(0xdeadbeef);
2179     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2180     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2181     DeleteObject(hdib);
2182
2183     bmi.bmiHeader.biSize = sizeof(BITMAPV5HEADER);
2184
2185     SetLastError(0xdeadbeef);
2186     hdib = CreateDIBSection(hdc, &bmi, 0, NULL, NULL, 0);
2187     ok(hdib != NULL ||
2188        broken(!hdib), /* Win95 */
2189        "CreateDIBSection error %d\n", GetLastError());
2190     DeleteObject(hdib);
2191
2192     memset(&bci, 0, sizeof(BITMAPCOREINFO));
2193     bci.bmciHeader.bcHeight = 100;
2194     bci.bmciHeader.bcWidth = 512;
2195     bci.bmciHeader.bcBitCount = 24;
2196     bci.bmciHeader.bcPlanes = 1;
2197
2198     bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER) - 1;
2199
2200     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2201     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2202
2203     bci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
2204
2205     SetLastError(0xdeadbeef);
2206     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2207     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
2208     DeleteObject(hdib);
2209
2210     bci.bmciHeader.bcSize++;
2211
2212     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2213     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2214
2215     bci.bmciHeader.bcSize = sizeof(BITMAPCOREINFO);
2216
2217     hdib = CreateDIBSection(hdc, (BITMAPINFO *)&bci, 0, NULL, NULL, 0);
2218     ok(hdib == NULL, "CreateDIBSection succeeded\n");
2219
2220     ReleaseDC(0, hdc);
2221 }
2222
2223 static void test_get16dibits(void)
2224 {
2225     BYTE bits[4 * (16 / sizeof(BYTE))];
2226     HBITMAP hbmp;
2227     HDC screen_dc = GetDC(NULL);
2228     int ret;
2229     BITMAPINFO * info;
2230     int info_len = sizeof(BITMAPINFOHEADER) + 1024;
2231     BYTE *p;
2232     int overwritten_bytes = 0;
2233
2234     memset(bits, 0, sizeof(bits));
2235     hbmp = CreateBitmap(2, 2, 1, 16, bits);
2236     ok(hbmp != NULL, "CreateBitmap failed\n");
2237
2238     info  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, info_len);
2239     assert(info);
2240
2241     memset(info, '!', info_len);
2242     memset(info, 0, sizeof(info->bmiHeader));
2243
2244     info->bmiHeader.biSize = sizeof(info->bmiHeader);
2245     info->bmiHeader.biWidth = 2;
2246     info->bmiHeader.biHeight = 2;
2247     info->bmiHeader.biPlanes = 1;
2248     info->bmiHeader.biCompression = BI_RGB;
2249
2250     ret = GetDIBits(screen_dc, hbmp, 0, 0, NULL, info, 0);
2251     ok(ret != 0 ||
2252        broken(ret == 0), /* win9x */
2253        "GetDIBits failed got %d\n", ret);
2254
2255     for (p = ((BYTE *) info) + sizeof(info->bmiHeader); (p - ((BYTE *) info)) < info_len; p++)
2256         if (*p != '!')
2257             overwritten_bytes++;
2258     ok(overwritten_bytes == 0, "GetDIBits wrote past the buffer given\n");
2259
2260     HeapFree(GetProcessHeap(), 0, info);
2261     DeleteObject(hbmp);
2262     ReleaseDC(NULL, screen_dc);
2263 }
2264
2265 static BOOL compare_buffers_no_alpha(UINT32 *a, UINT32 *b, int length)
2266 {
2267     int i;
2268     for(i = 0; i < length; i++)
2269         if((a[i] & 0x00FFFFFF) != (b[i] & 0x00FFFFFF))
2270             return FALSE;
2271     return TRUE;
2272 }
2273
2274 static void check_BitBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2275                                DWORD dwRop, UINT32 expected, int line)
2276 {
2277     *srcBuffer = 0xFEDCBA98;
2278     *dstBuffer = 0x89ABCDEF;
2279     Rectangle(hdcSrc, 0, 0, 1, 1);  /* A null operation to ensure dibs are coerced to X11 */
2280     BitBlt(hdcDst, 0, 0, 1, 1, hdcSrc, 0, 0, dwRop);
2281     ok(expected == *dstBuffer,
2282         "BitBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2283         dwRop, expected, *dstBuffer, line);
2284 }
2285
2286 static void test_BitBlt(void)
2287 {
2288     HBITMAP bmpDst, bmpSrc;
2289     HBITMAP oldDst, oldSrc;
2290     HDC hdcScreen, hdcDst, hdcSrc;
2291     UINT32 *dstBuffer, *srcBuffer;
2292     HBRUSH hBrush, hOldBrush;
2293     BITMAPINFO bitmapInfo;
2294
2295     memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2296     bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2297     bitmapInfo.bmiHeader.biWidth = 1;
2298     bitmapInfo.bmiHeader.biHeight = 1;
2299     bitmapInfo.bmiHeader.biPlanes = 1;
2300     bitmapInfo.bmiHeader.biBitCount = 32;
2301     bitmapInfo.bmiHeader.biCompression = BI_RGB;
2302     bitmapInfo.bmiHeader.biSizeImage = sizeof(UINT32);
2303
2304     hdcScreen = CreateCompatibleDC(0);
2305     hdcDst = CreateCompatibleDC(hdcScreen);
2306     hdcSrc = CreateCompatibleDC(hdcDst);
2307
2308     /* Setup the destination dib section */
2309     bmpDst = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&dstBuffer,
2310         NULL, 0);
2311     oldDst = SelectObject(hdcDst, bmpDst);
2312
2313     hBrush = CreateSolidBrush(0x012345678);
2314     hOldBrush = SelectObject(hdcDst, hBrush);
2315
2316     /* Setup the source dib section */
2317     bmpSrc = CreateDIBSection(hdcScreen, &bitmapInfo, DIB_RGB_COLORS, (void**)&srcBuffer,
2318         NULL, 0);
2319     oldSrc = SelectObject(hdcSrc, bmpSrc);
2320
2321     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2322     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2323     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2324     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2325     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2326     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2327     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2328     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2329     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2330     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2331     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2332     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2333     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2334     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2335     check_BitBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2336
2337     /* Tidy up */
2338     SelectObject(hdcSrc, oldSrc);
2339     DeleteObject(bmpSrc);
2340     DeleteDC(hdcSrc);
2341
2342     SelectObject(hdcDst, hOldBrush);
2343     DeleteObject(hBrush);
2344     SelectObject(hdcDst, oldDst);
2345     DeleteObject(bmpDst);
2346     DeleteDC(hdcDst);
2347
2348
2349     DeleteDC(hdcScreen);
2350 }
2351
2352 static void check_StretchBlt_pixel(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2353                                    DWORD dwRop, UINT32 expected, int line)
2354 {
2355     *srcBuffer = 0xFEDCBA98;
2356     *dstBuffer = 0x89ABCDEF;
2357     StretchBlt(hdcDst, 0, 0, 2, 1, hdcSrc, 0, 0, 1, 1, dwRop);
2358     ok(expected == *dstBuffer,
2359         "StretchBlt with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2360         dwRop, expected, *dstBuffer, line);
2361 }
2362
2363 static void check_StretchBlt_stretch(HDC hdcDst, HDC hdcSrc, UINT32 *dstBuffer, UINT32 *srcBuffer,
2364                                      int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2365                                      int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2366                                      UINT32 expected[4], UINT32 legacy_expected[4], int line)
2367 {
2368     memset(dstBuffer, 0, 16);
2369     StretchBlt(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2370                hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
2371     ok(memcmp(dstBuffer, expected, 16) == 0 ||
2372         broken(compare_buffers_no_alpha(dstBuffer, legacy_expected, 4)),
2373         "StretchBlt expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2374         "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2375         expected[0], expected[1], expected[2], expected[3],
2376         dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2377         nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2378         nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2379 }
2380
2381 static void test_StretchBlt(void)
2382 {
2383     HBITMAP bmpDst, bmpSrc;
2384     HBITMAP oldDst, oldSrc;
2385     HDC hdcScreen, hdcDst, hdcSrc;
2386     UINT32 *dstBuffer, *srcBuffer;
2387     HBRUSH hBrush, hOldBrush;
2388     BITMAPINFO biDst, biSrc;
2389     UINT32 expected[4], legacy_expected[4];
2390
2391     memset(&biDst, 0, sizeof(BITMAPINFO));
2392     biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2393     biDst.bmiHeader.biWidth = 2;
2394     biDst.bmiHeader.biHeight = -2;
2395     biDst.bmiHeader.biPlanes = 1;
2396     biDst.bmiHeader.biBitCount = 32;
2397     biDst.bmiHeader.biCompression = BI_RGB;
2398     memcpy(&biSrc, &biDst, sizeof(BITMAPINFO));
2399
2400     hdcScreen = CreateCompatibleDC(0);
2401     hdcDst = CreateCompatibleDC(hdcScreen);
2402     hdcSrc = CreateCompatibleDC(hdcDst);
2403
2404     /* Pixel Tests */
2405     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2406         NULL, 0);
2407     oldDst = SelectObject(hdcDst, bmpDst);
2408
2409     bmpSrc = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&srcBuffer,
2410         NULL, 0);
2411     oldSrc = SelectObject(hdcSrc, bmpSrc);
2412
2413     hBrush = CreateSolidBrush(0x012345678);
2414     hOldBrush = SelectObject(hdcDst, hBrush);
2415
2416     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2417     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2418     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2419     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2420     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2421     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2422     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2423     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2424     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2425     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2426     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2427     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2428     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2429     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2430     check_StretchBlt_pixel(hdcDst, hdcSrc, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2431
2432     SelectObject(hdcDst, hOldBrush);
2433     DeleteObject(hBrush);
2434
2435     /* Top-down to top-down tests */
2436     srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2437     srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2438
2439     expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2440     expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2441     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2442                              0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2443
2444     expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2445     expected[2] = 0x00000000, expected[3] = 0x00000000;
2446     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2447                              0, 0, 1, 1, 0, 0, 1, 1, expected, expected, __LINE__);
2448
2449     expected[0] = 0xCAFED00D, expected[1] = 0xCAFED00D;
2450     expected[2] = 0xCAFED00D, expected[3] = 0xCAFED00D;
2451     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2452                              0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
2453
2454     expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2455     expected[2] = 0x00000000, expected[3] = 0x00000000;
2456     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2457                              0, 0, 1, 1, 0, 0, 2, 2, expected, expected, __LINE__);
2458
2459     expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2460     expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2461     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2462                              0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2463
2464     expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2465     expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2466     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2467                              1, 1, -2, -2, 0, 0, 2, 2, expected, expected, __LINE__);
2468
2469     /* This result seems broken. One might expect the following result:
2470      * 0xCAFED00D 0xFEEDFACE
2471      * 0xFEDCBA98 0x76543210
2472      */
2473     expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2474     expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2475     legacy_expected[0] = 0xCAFED00D, legacy_expected[1] = 0x00000000;
2476     legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
2477     todo_wine check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2478                                        1, 1, -2, -2, 1, 1, -2, -2, expected,
2479                                        legacy_expected, __LINE__);
2480
2481     expected[0] = 0x00000000, expected[1] = 0x00000000;
2482     expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
2483     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2484                              1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2485
2486     SelectObject(hdcDst, oldDst);
2487     DeleteObject(bmpDst);
2488
2489     /* Top-down to bottom-up tests */
2490     biDst.bmiHeader.biHeight = 2;
2491     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2492         NULL, 0);
2493     oldDst = SelectObject(hdcDst, bmpDst);
2494
2495     expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2496     expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2497     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2498                              0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2499
2500     expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2501     expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2502     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2503                              0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2504
2505     SelectObject(hdcSrc, oldSrc);
2506     DeleteObject(bmpSrc);
2507
2508     /* Bottom-up to bottom-up tests */
2509     biSrc.bmiHeader.biHeight = 2;
2510     bmpSrc = CreateDIBSection(hdcScreen, &biSrc, DIB_RGB_COLORS, (void**)&srcBuffer,
2511         NULL, 0);
2512     srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2513     srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2514     oldSrc = SelectObject(hdcSrc, bmpSrc);
2515
2516     expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2517     expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2518     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2519                              0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2520
2521     expected[0] = 0x76543210, expected[1] = 0xFEDCBA98;
2522     expected[2] = 0xFEEDFACE, expected[3] = 0xCAFED00D;
2523     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2524                              0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2525
2526     SelectObject(hdcDst, oldDst);
2527     DeleteObject(bmpDst);
2528
2529     /* Bottom-up to top-down tests */
2530     biDst.bmiHeader.biHeight = -2;
2531     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2532         NULL, 0);
2533     oldDst = SelectObject(hdcDst, bmpDst);
2534
2535     expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2536     expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2537     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2538                              0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2539
2540     expected[0] = 0xFEEDFACE, expected[1] = 0xCAFED00D;
2541     expected[2] = 0x76543210, expected[3] = 0xFEDCBA98;
2542     check_StretchBlt_stretch(hdcDst, hdcSrc, dstBuffer, srcBuffer,
2543                              0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2544
2545     /* Tidy up */
2546     SelectObject(hdcSrc, oldSrc);
2547     DeleteObject(bmpSrc);
2548     DeleteDC(hdcSrc);
2549
2550     SelectObject(hdcDst, oldDst);
2551     DeleteObject(bmpDst);
2552     DeleteDC(hdcDst);
2553
2554     DeleteDC(hdcScreen);
2555 }
2556
2557 static void check_StretchDIBits_pixel(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
2558                                       DWORD dwRop, UINT32 expected, int line)
2559 {
2560     const UINT32 buffer[2] = { 0xFEDCBA98, 0 };
2561     BITMAPINFO bitmapInfo;
2562
2563     memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2564     bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2565     bitmapInfo.bmiHeader.biWidth = 2;
2566     bitmapInfo.bmiHeader.biHeight = 1;
2567     bitmapInfo.bmiHeader.biPlanes = 1;
2568     bitmapInfo.bmiHeader.biBitCount = 32;
2569     bitmapInfo.bmiHeader.biCompression = BI_RGB;
2570     bitmapInfo.bmiHeader.biSizeImage = sizeof(buffer);
2571
2572     *dstBuffer = 0x89ABCDEF;
2573
2574     StretchDIBits(hdcDst, 0, 0, 2, 1, 0, 0, 1, 1, &buffer, &bitmapInfo, DIB_RGB_COLORS, dwRop);
2575     ok(expected == *dstBuffer,
2576         "StretchDIBits with dwRop %06X. Expected 0x%08X, got 0x%08X from line %d\n",
2577         dwRop, expected, *dstBuffer, line);
2578 }
2579
2580 static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer,
2581                                         int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
2582                                         int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
2583                                         UINT32 expected[4], UINT32 legacy_expected[4], int line)
2584 {
2585     BITMAPINFO bitmapInfo;
2586
2587     memset(&bitmapInfo, 0, sizeof(BITMAPINFO));
2588     bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2589     bitmapInfo.bmiHeader.biWidth = 2;
2590     bitmapInfo.bmiHeader.biHeight = -2;
2591     bitmapInfo.bmiHeader.biPlanes = 1;
2592     bitmapInfo.bmiHeader.biBitCount = 32;
2593     bitmapInfo.bmiHeader.biCompression = BI_RGB;
2594
2595     memset(dstBuffer, 0, 16);
2596     StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
2597                   nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2598                   srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
2599     ok(memcmp(dstBuffer, expected, 16) == 0 ||                              /* Win2k/XP */
2600         broken(compare_buffers_no_alpha(dstBuffer, legacy_expected, 4)) ||  /* Win9X/ME */
2601         broken(nWidthSrc < 0 || nHeightSrc < 0),                            /* Win9X/ME */
2602         "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } "
2603         "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n",
2604         expected[0], expected[1], expected[2], expected[3],
2605         dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3],
2606         nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,
2607         nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line);
2608 }
2609
2610 static void test_StretchDIBits(void)
2611 {
2612     HBITMAP bmpDst;
2613     HBITMAP oldDst;
2614     HDC hdcScreen, hdcDst;
2615     UINT32 *dstBuffer, srcBuffer[4];
2616     HBRUSH hBrush, hOldBrush;
2617     BITMAPINFO biDst;
2618     UINT32 expected[4], legacy_expected[4];
2619
2620     memset(&biDst, 0, sizeof(BITMAPINFO));
2621     biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2622     biDst.bmiHeader.biWidth = 2;
2623     biDst.bmiHeader.biHeight = -2;
2624     biDst.bmiHeader.biPlanes = 1;
2625     biDst.bmiHeader.biBitCount = 32;
2626     biDst.bmiHeader.biCompression = BI_RGB;
2627
2628     hdcScreen = CreateCompatibleDC(0);
2629     hdcDst = CreateCompatibleDC(hdcScreen);
2630
2631     /* Pixel Tests */
2632     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2633         NULL, 0);
2634     oldDst = SelectObject(hdcDst, bmpDst);
2635
2636     hBrush = CreateSolidBrush(0x012345678);
2637     hOldBrush = SelectObject(hdcDst, hBrush);
2638
2639     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCCOPY, 0xFEDCBA98, __LINE__);
2640     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCPAINT, 0xFFFFFFFF, __LINE__);
2641     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCAND, 0x88888888, __LINE__);
2642     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCINVERT, 0x77777777, __LINE__);
2643     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, SRCERASE, 0x76543210, __LINE__);
2644     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCCOPY, 0x01234567, __LINE__);
2645     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, NOTSRCERASE, 0x00000000, __LINE__);
2646     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGECOPY, 0x00581210, __LINE__);
2647     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, MERGEPAINT, 0x89ABCDEF, __LINE__);
2648     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATCOPY, 0x00785634, __LINE__);
2649     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATPAINT, 0x89FBDFFF, __LINE__);
2650     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, PATINVERT, 0x89D39BDB, __LINE__);
2651     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, DSTINVERT, 0x76543210, __LINE__);
2652     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, BLACKNESS, 0x00000000, __LINE__);
2653     check_StretchDIBits_pixel(hdcDst, dstBuffer, srcBuffer, WHITENESS, 0xFFFFFFFF, __LINE__);
2654
2655     SelectObject(hdcDst, hOldBrush);
2656     DeleteObject(hBrush);
2657
2658     /* Top-down destination tests */
2659     srcBuffer[0] = 0xCAFED00D, srcBuffer[1] = 0xFEEDFACE;
2660     srcBuffer[2] = 0xFEDCBA98, srcBuffer[3] = 0x76543210;
2661
2662     expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE;
2663     expected[2] = 0xFEDCBA98, expected[3] = 0x76543210;
2664     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2665                                 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2666
2667     expected[0] = 0xCAFED00D, expected[1] = 0x00000000;
2668     expected[2] = 0x00000000, expected[3] = 0x00000000;
2669     legacy_expected[0] = 0xFEDCBA98, legacy_expected[1] = 0x00000000;
2670     legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
2671     todo_wine check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2672                                 0, 0, 1, 1, 0, 0, 1, 1, expected, legacy_expected, __LINE__);
2673
2674     expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98;
2675     expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98;
2676     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2677                                 0, 0, 2, 2, 0, 0, 1, 1, expected, expected, __LINE__);
2678
2679     expected[0] = 0x42441000, expected[1] = 0x00000000;
2680     expected[2] = 0x00000000, expected[3] = 0x00000000;
2681     legacy_expected[0] = 0x00543210, legacy_expected[1] = 0x00000000;
2682     legacy_expected[2] = 0x00000000, legacy_expected[3] = 0x00000000;
2683     todo_wine check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2684                                 0, 0, 1, 1, 0, 0, 2, 2, expected, legacy_expected, __LINE__);
2685
2686     expected[0] = 0x00000000, expected[1] = 0x00000000;
2687     expected[2] = 0x00000000, expected[3] = 0x00000000;
2688     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2689                                 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2690
2691     expected[0] = 0x00000000, expected[1] = 0x00000000;
2692     expected[2] = 0x00000000, expected[3] = 0x00000000;
2693     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2694                                 0, 0, 2, 2, 1, 1, -2, -2, expected, expected, __LINE__);
2695
2696     expected[0] = 0x00000000, expected[1] = 0x00000000;
2697     expected[2] = 0x00000000, expected[3] = 0x00000000;
2698     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2699                                 1, 1, -2, -2, 1, 1, -2, -2, expected, expected, __LINE__);
2700
2701     expected[0] = 0x00000000, expected[1] = 0x00000000;
2702     expected[2] = 0x00000000, expected[3] = 0xCAFED00D;
2703     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2704                                 1, 1, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2705
2706     SelectObject(hdcDst, oldDst);
2707     DeleteObject(bmpDst);
2708
2709     /* Bottom up destination tests */
2710     biDst.bmiHeader.biHeight = 2;
2711     bmpDst = CreateDIBSection(hdcScreen, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer,
2712         NULL, 0);
2713     oldDst = SelectObject(hdcDst, bmpDst);
2714
2715     expected[0] = 0xFEDCBA98, expected[1] = 0x76543210;
2716     expected[2] = 0xCAFED00D, expected[3] = 0xFEEDFACE;
2717     check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer,
2718                                 0, 0, 2, 2, 0, 0, 2, 2, expected, expected, __LINE__);
2719
2720     /* Tidy up */
2721     SelectObject(hdcDst, oldDst);
2722     DeleteObject(bmpDst);
2723     DeleteDC(hdcDst);
2724
2725     DeleteDC(hdcScreen);
2726 }
2727
2728 static void test_GdiAlphaBlend(void)
2729 {
2730     /* test out-of-bound parameters for GdiAlphaBlend */
2731     HDC hdcNull;
2732
2733     HDC hdcDst;
2734     HBITMAP bmpDst;
2735     HBITMAP oldDst;
2736
2737     BITMAPINFO bmi;
2738     HDC hdcSrc;
2739     HBITMAP bmpSrc;
2740     HBITMAP oldSrc;
2741     LPVOID bits;
2742
2743     BLENDFUNCTION blend;
2744
2745     if (!pGdiAlphaBlend)
2746     {
2747         win_skip("GdiAlphaBlend() is not implemented\n");
2748         return;
2749     }
2750
2751     hdcNull = GetDC(NULL);
2752     hdcDst = CreateCompatibleDC(hdcNull);
2753     bmpDst = CreateCompatibleBitmap(hdcNull, 100, 100);
2754     hdcSrc = CreateCompatibleDC(hdcNull);
2755
2756     memset(&bmi, 0, sizeof(bmi));  /* as of Wine 0.9.44 we require the src to be a DIB section */
2757     bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
2758     bmi.bmiHeader.biHeight = 20;
2759     bmi.bmiHeader.biWidth = 20;
2760     bmi.bmiHeader.biBitCount = 32;
2761     bmi.bmiHeader.biPlanes = 1;
2762     bmi.bmiHeader.biCompression = BI_RGB;
2763     bmpSrc = CreateDIBSection(hdcDst, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
2764     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
2765
2766     oldDst = SelectObject(hdcDst, bmpDst);
2767     oldSrc = SelectObject(hdcSrc, bmpSrc);
2768
2769     blend.BlendOp = AC_SRC_OVER;
2770     blend.BlendFlags = 0;
2771     blend.SourceConstantAlpha = 128;
2772     blend.AlphaFormat = 0;
2773
2774     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, 0, 20, 20, blend), TRUE, BOOL, "%d");
2775     SetLastError(0xdeadbeef);
2776     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), FALSE, BOOL, "%d");
2777     expect_eq(GetLastError(), ERROR_INVALID_PARAMETER, int, "%d");
2778     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), FALSE, BOOL, "%d");
2779     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 15, 0, 10, 10, blend), FALSE, BOOL, "%d");
2780     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
2781     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 10, 10, -2, 3, blend), FALSE, BOOL, "%d");
2782
2783     SetWindowOrgEx(hdcSrc, -10, -10, NULL);
2784     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 10, 10, blend), TRUE, BOOL, "%d");
2785     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 10, 10, blend), TRUE, BOOL, "%d");
2786     SetMapMode(hdcSrc, MM_ANISOTROPIC);
2787     ScaleWindowExtEx(hdcSrc, 10, 1, 10, 1, NULL);
2788     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, -1, 0, 30, 30, blend), TRUE, BOOL, "%d");
2789     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 30, 30, blend), TRUE, BOOL, "%d");
2790
2791     SetLastError(0xdeadbeef);
2792     expect_eq(pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, NULL, 0, 0, 20, 20, blend), FALSE, BOOL, "%d");
2793     expect_eq(GetLastError(), 0xdeadbeef, int, "%d");
2794
2795     SelectObject(hdcDst, oldDst);
2796     SelectObject(hdcSrc, oldSrc);
2797     DeleteObject(bmpSrc);
2798     DeleteObject(bmpDst);
2799     DeleteDC(hdcDst);
2800     DeleteDC(hdcSrc);
2801
2802     ReleaseDC(NULL, hdcNull);
2803
2804 }
2805
2806 static void test_clipping(void)
2807 {
2808     HBITMAP bmpDst;
2809     HBITMAP oldDst;
2810     HBITMAP bmpSrc;
2811     HBITMAP oldSrc;
2812     HRGN hRgn;
2813     LPVOID bits;
2814     BOOL result;
2815
2816     HDC hdcDst = CreateCompatibleDC( NULL );
2817     HDC hdcSrc = CreateCompatibleDC( NULL );
2818
2819     BITMAPINFO bmpinfo={{0}};
2820     bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2821     bmpinfo.bmiHeader.biWidth = 100;
2822     bmpinfo.bmiHeader.biHeight = 100;
2823     bmpinfo.bmiHeader.biPlanes = 1;
2824     bmpinfo.bmiHeader.biBitCount = GetDeviceCaps( hdcDst, BITSPIXEL );
2825     bmpinfo.bmiHeader.biCompression = BI_RGB;
2826
2827     bmpDst = CreateDIBSection( hdcDst, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
2828     ok(bmpDst != NULL, "Couldn't create destination bitmap\n");
2829     oldDst = SelectObject( hdcDst, bmpDst );
2830
2831     bmpSrc = CreateDIBSection( hdcSrc, &bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
2832     ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
2833     oldSrc = SelectObject( hdcSrc, bmpSrc );
2834
2835     result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 100, 100, SRCCOPY );
2836     ok(result, "BitBlt failed\n");
2837
2838     hRgn = CreateRectRgn( 0,0,0,0 );
2839     SelectClipRgn( hdcDst, hRgn );
2840
2841     result = BitBlt( hdcDst, 0, 0, 100, 100, hdcSrc, 0, 0, SRCCOPY );
2842     ok(result, "BitBlt failed\n");
2843
2844     DeleteObject( bmpDst );
2845     DeleteObject( bmpSrc );
2846     DeleteObject( hRgn );
2847     DeleteDC( hdcDst );
2848     DeleteDC( hdcSrc );
2849 }
2850
2851 START_TEST(bitmap)
2852 {
2853     HMODULE hdll;
2854     is_win9x = GetWindowLongPtrW(GetDesktopWindow(), GWLP_WNDPROC) == 0;
2855
2856     hdll = GetModuleHandle("gdi32.dll");
2857     pGdiAlphaBlend = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
2858
2859     test_createdibitmap();
2860     test_dibsections();
2861     test_mono_dibsection();
2862     test_bitmap();
2863     test_bmBits();
2864     test_GetDIBits_selected_DIB(1);
2865     test_GetDIBits_selected_DIB(4);
2866     test_GetDIBits_selected_DIB(8);
2867     test_GetDIBits_selected_DDB(TRUE);
2868     test_GetDIBits_selected_DDB(FALSE);
2869     test_GetDIBits();
2870     test_GetDIBits_BI_BITFIELDS();
2871     test_select_object();
2872     test_CreateBitmap();
2873     test_BitBlt();
2874     test_StretchBlt();
2875     test_StretchDIBits();
2876     test_GdiAlphaBlend();
2877     test_bitmapinfoheadersize();
2878     test_get16dibits();
2879     test_clipping();
2880 }