Update the address of the Free Software Foundation.
[wine/gsoc_dplay.git] / dlls / gdi / tests / pen.c
blob4c93348adc25d63662cad1f046dc4f82b0866d42
1 /*
2 * Unit test suite for pens
4 * Copyright 2006 Dmitry Timoshkov
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
22 #include <assert.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wingdi.h"
27 #include "winuser.h"
29 #include "wine/test.h"
31 static void test_logpen(void)
33 static const struct
35 UINT style;
36 INT width;
37 COLORREF color;
38 UINT ret_style;
39 INT ret_width;
40 COLORREF ret_color;
41 } pen[] = {
42 { PS_SOLID, -123, RGB(0x12,0x34,0x56), PS_SOLID, 123, RGB(0x12,0x34,0x56) },
43 { PS_SOLID, 0, RGB(0x12,0x34,0x56), PS_SOLID, 0, RGB(0x12,0x34,0x56) },
44 { PS_SOLID, 123, RGB(0x12,0x34,0x56), PS_SOLID, 123, RGB(0x12,0x34,0x56) },
45 { PS_DASH, 123, RGB(0x12,0x34,0x56), PS_DASH, 123, RGB(0x12,0x34,0x56) },
46 { PS_DOT, 123, RGB(0x12,0x34,0x56), PS_DOT, 123, RGB(0x12,0x34,0x56) },
47 { PS_DASHDOT, 123, RGB(0x12,0x34,0x56), PS_DASHDOT, 123, RGB(0x12,0x34,0x56) },
48 { PS_DASHDOTDOT, 123, RGB(0x12,0x34,0x56), PS_DASHDOTDOT, 123, RGB(0x12,0x34,0x56) },
49 { PS_NULL, -123, RGB(0x12,0x34,0x56), PS_NULL, 1, 0 },
50 { PS_NULL, 123, RGB(0x12,0x34,0x56), PS_NULL, 1, 0 },
51 { PS_INSIDEFRAME, 123, RGB(0x12,0x34,0x56), PS_INSIDEFRAME, 123, RGB(0x12,0x34,0x56) },
52 { PS_USERSTYLE, 123, RGB(0x12,0x34,0x56), PS_SOLID, 123, RGB(0x12,0x34,0x56) },
53 { PS_ALTERNATE, 123, RGB(0x12,0x34,0x56), PS_SOLID, 123, RGB(0x12,0x34,0x56) }
55 INT i, size;
56 HPEN hpen;
57 LOGPEN lp;
58 EXTLOGPEN elp;
59 LOGBRUSH lb;
60 DWORD obj_type, user_style[2] = { 0xabc, 0xdef };
61 struct
63 EXTLOGPEN elp;
64 DWORD style_data[10];
65 } ext_pen;
67 for (i = 0; i < sizeof(pen)/sizeof(pen[0]); i++)
69 trace("testing style %u\n", pen[i].style);
71 /********************** cosmetic pens **********************/
72 /* CreatePenIndirect behaviour */
73 lp.lopnStyle = pen[i].style,
74 lp.lopnWidth.x = pen[i].width;
75 lp.lopnWidth.y = 11; /* just in case */
76 lp.lopnColor = pen[i].color;
77 SetLastError(0xdeadbeef);
78 hpen = CreatePenIndirect(&lp);
79 ok(hpen != 0, "CreatePen error %ld\n", GetLastError());
81 obj_type = GetObjectType(hpen);
82 ok(obj_type == OBJ_PEN, "wrong object type %lu\n", obj_type);
84 memset(&lp, 0xb0, sizeof(lp));
85 SetLastError(0xdeadbeef);
86 size = GetObject(hpen, sizeof(lp), &lp);
87 ok(size == sizeof(lp), "GetObject returned %d, error %ld\n", size, GetLastError());
89 ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
90 ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %ld\n", pen[i].ret_width, lp.lopnWidth.x);
91 ok(lp.lopnWidth.y == 0, "expected 0, got %ld\n", lp.lopnWidth.y);
92 ok(lp.lopnColor == pen[i].ret_color, "expected %08lx, got %08lx\n", pen[i].ret_color, lp.lopnColor);
94 DeleteObject(hpen);
96 /* CreatePen behaviour */
97 SetLastError(0xdeadbeef);
98 hpen = CreatePen(pen[i].style, pen[i].width, pen[i].color);
99 ok(hpen != 0, "CreatePen error %ld\n", GetLastError());
101 obj_type = GetObjectType(hpen);
102 ok(obj_type == OBJ_PEN, "wrong object type %lu\n", obj_type);
104 /* check what's the real size of the object */
105 size = GetObject(hpen, 0, NULL);
106 ok(size == sizeof(lp), "GetObject returned %d, error %ld\n", size, GetLastError());
108 /* ask for truncated data */
109 memset(&lp, 0xb0, sizeof(lp));
110 SetLastError(0xdeadbeef);
111 size = GetObject(hpen, sizeof(lp.lopnStyle), &lp);
112 ok(!size, "GetObject should fail: size %d, error %ld\n", size, GetLastError());
114 /* see how larger buffer sizes are handled */
115 memset(&lp, 0xb0, sizeof(lp));
116 SetLastError(0xdeadbeef);
117 size = GetObject(hpen, sizeof(lp) * 2, &lp);
118 ok(size == sizeof(lp), "GetObject returned %d, error %ld\n", size, GetLastError());
120 /* see how larger buffer sizes are handled */
121 memset(&elp, 0xb0, sizeof(elp));
122 SetLastError(0xdeadbeef);
123 size = GetObject(hpen, sizeof(elp) * 2, &elp);
124 ok(size == sizeof(lp), "GetObject returned %d, error %ld\n", size, GetLastError());
126 memset(&lp, 0xb0, sizeof(lp));
127 SetLastError(0xdeadbeef);
128 size = GetObject(hpen, sizeof(lp), &lp);
129 ok(size == sizeof(lp), "GetObject returned %d, error %ld\n", size, GetLastError());
131 ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
132 ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %ld\n", pen[i].ret_width, lp.lopnWidth.x);
133 ok(lp.lopnWidth.y == 0, "expected 0, got %ld\n", lp.lopnWidth.y);
134 ok(lp.lopnColor == pen[i].ret_color, "expected %08lx, got %08lx\n", pen[i].ret_color, lp.lopnColor);
136 memset(&elp, 0xb0, sizeof(elp));
137 SetLastError(0xdeadbeef);
138 size = GetObject(hpen, sizeof(elp), &elp);
140 /* for some reason XP differentiates PS_NULL here */
141 if (pen[i].style == PS_NULL)
143 ok(size == sizeof(EXTLOGPEN), "GetObject returned %d, error %ld\n", size, GetLastError());
144 ok(elp.elpPenStyle == pen[i].ret_style, "expected %u, got %lu\n", pen[i].ret_style, elp.elpPenStyle);
145 ok(elp.elpWidth == 0, "expected 0, got %lu\n", elp.elpWidth);
146 ok(elp.elpColor == pen[i].ret_color, "expected %08lx, got %08lx\n", pen[i].ret_color, elp.elpColor);
147 ok(elp.elpBrushStyle == BS_SOLID, "expected BS_SOLID, got %u\n", elp.elpBrushStyle);
148 ok(elp.elpHatch == 0, "expected 0, got %p\n", (void *)elp.elpHatch);
149 ok(elp.elpNumEntries == 0, "expected 0, got %lx\n", elp.elpNumEntries);
151 else
153 ok(size == sizeof(LOGPEN), "GetObject returned %d, error %ld\n", size, GetLastError());
154 memcpy(&lp, &elp, sizeof(lp));
155 ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
156 ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %ld\n", pen[i].ret_width, lp.lopnWidth.x);
157 ok(lp.lopnWidth.y == 0, "expected 0, got %ld\n", lp.lopnWidth.y);
158 ok(lp.lopnColor == pen[i].ret_color, "expected %08lx, got %08lx\n", pen[i].ret_color, lp.lopnColor);
161 DeleteObject(hpen);
163 /********** cosmetic pens created by ExtCreatePen ***********/
164 lb.lbStyle = BS_SOLID;
165 lb.lbColor = pen[i].color;
166 lb.lbHatch = HS_CROSS; /* just in case */
167 SetLastError(0xdeadbeef);
168 hpen = ExtCreatePen(pen[i].style, pen[i].width, &lb, 2, user_style);
169 if (pen[i].style != PS_USERSTYLE)
171 ok(hpen == 0, "ExtCreatePen should fail\n");
172 ok(GetLastError() == ERROR_INVALID_PARAMETER,
173 "wrong last error value %ld\n", GetLastError());
174 SetLastError(0xdeadbeef);
175 hpen = ExtCreatePen(pen[i].style, pen[i].width, &lb, 0, NULL);
176 if (pen[i].style != PS_NULL)
178 ok(hpen == 0, "ExtCreatePen with width != 1 should fail\n");
179 ok(GetLastError() == ERROR_INVALID_PARAMETER,
180 "wrong last error value %ld\n", GetLastError());
182 SetLastError(0xdeadbeef);
183 hpen = ExtCreatePen(pen[i].style, 1, &lb, 0, NULL);
186 else
188 ok(hpen == 0, "ExtCreatePen with width != 1 should fail\n");
189 ok(GetLastError() == ERROR_INVALID_PARAMETER,
190 "wrong last error value %ld\n", GetLastError());
191 SetLastError(0xdeadbeef);
192 hpen = ExtCreatePen(pen[i].style, 1, &lb, 2, user_style);
194 if (pen[i].style == PS_INSIDEFRAME)
196 /* This style is applicable only for gemetric pens */
197 ok(hpen == 0, "ExtCreatePen should fail\n");
198 goto test_geometric_pens;
200 ok(hpen != 0, "ExtCreatePen error %ld\n", GetLastError());
202 obj_type = GetObjectType(hpen);
203 /* for some reason XP differentiates PS_NULL here */
204 if (pen[i].style == PS_NULL)
205 ok(obj_type == OBJ_PEN, "wrong object type %lu\n", obj_type);
206 else
207 ok(obj_type == OBJ_EXTPEN, "wrong object type %lu\n", obj_type);
209 /* check what's the real size of the object */
210 SetLastError(0xdeadbeef);
211 size = GetObject(hpen, 0, NULL);
212 switch (pen[i].style)
214 case PS_NULL:
215 ok(size == sizeof(LOGPEN),
216 "GetObject returned %d, error %ld\n", size, GetLastError());
217 break;
219 case PS_USERSTYLE:
220 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry) + sizeof(user_style),
221 "GetObject returned %d, error %ld\n", size, GetLastError());
222 break;
224 default:
225 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry),
226 "GetObject returned %d, error %ld\n", size, GetLastError());
227 break;
230 /* ask for truncated data */
231 memset(&elp, 0xb0, sizeof(elp));
232 SetLastError(0xdeadbeef);
233 size = GetObject(hpen, sizeof(elp.elpPenStyle), &elp);
234 ok(!size, "GetObject should fail: size %d, error %ld\n", size, GetLastError());
236 /* see how larger buffer sizes are handled */
237 memset(&ext_pen, 0xb0, sizeof(ext_pen));
238 SetLastError(0xdeadbeef);
239 size = GetObject(hpen, sizeof(ext_pen), &ext_pen.elp);
240 switch (pen[i].style)
242 case PS_NULL:
243 ok(size == sizeof(LOGPEN),
244 "GetObject returned %d, error %ld\n", size, GetLastError());
245 memcpy(&lp, &ext_pen.elp, sizeof(lp));
246 ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
247 ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %ld\n", pen[i].ret_width, lp.lopnWidth.x);
248 ok(lp.lopnWidth.y == 0, "expected 0, got %ld\n", lp.lopnWidth.y);
249 ok(lp.lopnColor == pen[i].ret_color, "expected %08lx, got %08lx\n", pen[i].ret_color, lp.lopnColor);
251 /* for PS_NULL it also works this way */
252 memset(&elp, 0xb0, sizeof(elp));
253 SetLastError(0xdeadbeef);
254 size = GetObject(hpen, sizeof(elp), &elp);
255 ok(size == sizeof(EXTLOGPEN),
256 "GetObject returned %d, error %ld\n", size, GetLastError());
257 ok(ext_pen.elp.elpHatch == 0xb0b0b0b0, "expected 0xb0b0b0b0, got %p\n", (void *)ext_pen.elp.elpHatch);
258 ok(ext_pen.elp.elpNumEntries == 0xb0b0b0b0, "expected 0xb0b0b0b0, got %lx\n", ext_pen.elp.elpNumEntries);
259 break;
261 case PS_USERSTYLE:
262 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry) + sizeof(user_style),
263 "GetObject returned %d, error %ld\n", size, GetLastError());
264 ok(ext_pen.elp.elpHatch == HS_CROSS, "expected HS_CROSS, got %p\n", (void *)ext_pen.elp.elpHatch);
265 ok(ext_pen.elp.elpNumEntries == 2, "expected 0, got %lx\n", ext_pen.elp.elpNumEntries);
266 ok(ext_pen.elp.elpStyleEntry[0] == 0xabc, "expected 0xabc, got %lx\n", ext_pen.elp.elpStyleEntry[0]);
267 ok(ext_pen.elp.elpStyleEntry[1] == 0xdef, "expected 0xabc, got %lx\n", ext_pen.elp.elpStyleEntry[1]);
268 break;
270 default:
271 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry),
272 "GetObject returned %d, error %ld\n", size, GetLastError());
273 ok(ext_pen.elp.elpHatch == HS_CROSS, "expected HS_CROSS, got %p\n", (void *)ext_pen.elp.elpHatch);
274 ok(ext_pen.elp.elpNumEntries == 0, "expected 0, got %lx\n", ext_pen.elp.elpNumEntries);
275 break;
278 if (pen[i].style == PS_USERSTYLE)
280 todo_wine
281 ok(ext_pen.elp.elpPenStyle == pen[i].style, "expected %x, got %lx\n", pen[i].style, ext_pen.elp.elpPenStyle);
283 else
284 ok(ext_pen.elp.elpPenStyle == pen[i].style, "expected %x, got %lx\n", pen[i].style, ext_pen.elp.elpPenStyle);
285 ok(ext_pen.elp.elpWidth == 1, "expected 1, got %lx\n", ext_pen.elp.elpWidth);
286 ok(ext_pen.elp.elpColor == pen[i].ret_color, "expected %08lx, got %08lx\n", pen[i].ret_color, ext_pen.elp.elpColor);
287 ok(ext_pen.elp.elpBrushStyle == BS_SOLID, "expected BS_SOLID, got %x\n", ext_pen.elp.elpBrushStyle);
289 DeleteObject(hpen);
291 test_geometric_pens:
292 /********************** geometric pens **********************/
293 lb.lbStyle = BS_SOLID;
294 lb.lbColor = pen[i].color;
295 lb.lbHatch = HS_CROSS; /* just in case */
296 SetLastError(0xdeadbeef);
297 hpen = ExtCreatePen(PS_GEOMETRIC | pen[i].style, pen[i].width, &lb, 2, user_style);
298 if (pen[i].style != PS_USERSTYLE)
300 ok(hpen == 0, "ExtCreatePen should fail\n");
301 SetLastError(0xdeadbeef);
302 hpen = ExtCreatePen(PS_GEOMETRIC | pen[i].style, pen[i].width, &lb, 0, NULL);
304 if (pen[i].style == PS_ALTERNATE)
306 /* This style is applicable only for cosmetic pens */
307 ok(hpen == 0, "ExtCreatePen should fail\n");
308 continue;
310 ok(hpen != 0, "ExtCreatePen error %ld\n", GetLastError());
312 obj_type = GetObjectType(hpen);
313 /* for some reason XP differentiates PS_NULL here */
314 if (pen[i].style == PS_NULL)
315 ok(obj_type == OBJ_PEN, "wrong object type %lu\n", obj_type);
316 else
317 ok(obj_type == OBJ_EXTPEN, "wrong object type %lu\n", obj_type);
319 /* check what's the real size of the object */
320 size = GetObject(hpen, 0, NULL);
321 switch (pen[i].style)
323 case PS_NULL:
324 ok(size == sizeof(LOGPEN),
325 "GetObject returned %d, error %ld\n", size, GetLastError());
326 break;
328 case PS_USERSTYLE:
329 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry) + sizeof(user_style),
330 "GetObject returned %d, error %ld\n", size, GetLastError());
331 break;
333 default:
334 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry),
335 "GetObject returned %d, error %ld\n", size, GetLastError());
336 break;
339 /* ask for truncated data */
340 memset(&lp, 0xb0, sizeof(lp));
341 SetLastError(0xdeadbeef);
342 size = GetObject(hpen, sizeof(lp.lopnStyle), &lp);
343 ok(!size, "GetObject should fail: size %d, error %ld\n", size, GetLastError());
345 memset(&lp, 0xb0, sizeof(lp));
346 SetLastError(0xdeadbeef);
347 size = GetObject(hpen, sizeof(lp), &lp);
348 /* for some reason XP differenciates PS_NULL here */
349 if (pen[i].style == PS_NULL)
351 ok(size == sizeof(LOGPEN), "GetObject returned %d, error %ld\n", size, GetLastError());
352 ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
353 ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %ld\n", pen[i].ret_width, lp.lopnWidth.x);
354 ok(lp.lopnWidth.y == 0, "expected 0, got %ld\n", lp.lopnWidth.y);
355 ok(lp.lopnColor == pen[i].ret_color, "expected %08lx, got %08lx\n", pen[i].ret_color, lp.lopnColor);
357 else
358 /* XP doesn't set last error here */
359 ok(!size /*&& GetLastError() == ERROR_INVALID_PARAMETER*/,
360 "GetObject should fail: size %d, error %ld\n", size, GetLastError());
362 memset(&ext_pen, 0xb0, sizeof(ext_pen));
363 SetLastError(0xdeadbeef);
364 /* buffer is too small for user styles */
365 size = GetObject(hpen, sizeof(elp), &ext_pen.elp);
366 switch (pen[i].style)
368 case PS_NULL:
369 ok(size == sizeof(EXTLOGPEN),
370 "GetObject returned %d, error %ld\n", size, GetLastError());
371 ok(ext_pen.elp.elpHatch == 0, "expected 0, got %p\n", (void *)ext_pen.elp.elpHatch);
372 ok(ext_pen.elp.elpNumEntries == 0, "expected 0, got %lx\n", ext_pen.elp.elpNumEntries);
374 /* for PS_NULL it also works this way */
375 SetLastError(0xdeadbeef);
376 size = GetObject(hpen, sizeof(ext_pen), &lp);
377 ok(size == sizeof(LOGPEN),
378 "GetObject returned %d, error %ld\n", size, GetLastError());
379 ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
380 ok(lp.lopnWidth.x == pen[i].ret_width, "expected %u, got %ld\n", pen[i].ret_width, lp.lopnWidth.x);
381 ok(lp.lopnWidth.y == 0, "expected 0, got %ld\n", lp.lopnWidth.y);
382 ok(lp.lopnColor == pen[i].ret_color, "expected %08lx, got %08lx\n", pen[i].ret_color, lp.lopnColor);
383 break;
385 case PS_USERSTYLE:
386 ok(!size /*&& GetLastError() == ERROR_INVALID_PARAMETER*/,
387 "GetObject should fail: size %d, error %ld\n", size, GetLastError());
388 size = GetObject(hpen, sizeof(ext_pen), &ext_pen.elp);
389 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry) + sizeof(user_style),
390 "GetObject returned %d, error %ld\n", size, GetLastError());
391 ok(ext_pen.elp.elpHatch == HS_CROSS, "expected HS_CROSS, got %p\n", (void *)ext_pen.elp.elpHatch);
392 ok(ext_pen.elp.elpNumEntries == 2, "expected 0, got %lx\n", ext_pen.elp.elpNumEntries);
393 ok(ext_pen.elp.elpStyleEntry[0] == 0xabc, "expected 0xabc, got %lx\n", ext_pen.elp.elpStyleEntry[0]);
394 ok(ext_pen.elp.elpStyleEntry[1] == 0xdef, "expected 0xabc, got %lx\n", ext_pen.elp.elpStyleEntry[1]);
395 break;
397 default:
398 ok(size == sizeof(EXTLOGPEN) - sizeof(elp.elpStyleEntry),
399 "GetObject returned %d, error %ld\n", size, GetLastError());
400 ok(ext_pen.elp.elpHatch == HS_CROSS, "expected HS_CROSS, got %p\n", (void *)ext_pen.elp.elpHatch);
401 ok(ext_pen.elp.elpNumEntries == 0, "expected 0, got %lx\n", ext_pen.elp.elpNumEntries);
402 break;
405 /* for some reason XP differenciates PS_NULL here */
406 if (pen[i].style == PS_NULL)
407 ok(ext_pen.elp.elpPenStyle == pen[i].ret_style, "expected %x, got %lx\n", pen[i].ret_style, ext_pen.elp.elpPenStyle);
408 else
410 if (pen[i].style == PS_USERSTYLE)
412 todo_wine
413 ok(ext_pen.elp.elpPenStyle == (PS_GEOMETRIC | pen[i].style), "expected %x, got %lx\n", PS_GEOMETRIC | pen[i].style, ext_pen.elp.elpPenStyle);
415 else
416 ok(ext_pen.elp.elpPenStyle == (PS_GEOMETRIC | pen[i].style), "expected %x, got %lx\n", PS_GEOMETRIC | pen[i].style, ext_pen.elp.elpPenStyle);
419 if (pen[i].style == PS_NULL)
420 ok(ext_pen.elp.elpWidth == 0, "expected 0, got %lx\n", ext_pen.elp.elpWidth);
421 else
422 ok(ext_pen.elp.elpWidth == pen[i].ret_width, "expected %u, got %lx\n", pen[i].ret_width, ext_pen.elp.elpWidth);
423 ok(ext_pen.elp.elpColor == pen[i].ret_color, "expected %08lx, got %08lx\n", pen[i].ret_color, ext_pen.elp.elpColor);
424 ok(ext_pen.elp.elpBrushStyle == BS_SOLID, "expected BS_SOLID, got %x\n", ext_pen.elp.elpBrushStyle);
426 DeleteObject(hpen);
430 START_TEST(pen)
432 test_logpen();