Made the Interlocked*Pointer functions static inline since they aren't
[wine/multimedia.git] / objects / brush.c
blobcef8f523c86cc4a4d687fe1cb58477fe366aa9af
1 /*
2 * GDI brush objects
4 * Copyright 1993, 1994 Alexandre Julliard
5 */
7 #include "config.h"
9 #include <string.h>
11 #include "winbase.h"
12 #include "wingdi.h"
14 #include "wine/wingdi16.h"
15 #include "bitmap.h"
16 #include "brush.h"
18 #include "debugtools.h"
20 DEFAULT_DEBUG_CHANNEL(gdi);
22 static HGLOBAL16 dib_copy(BITMAPINFO *info, UINT coloruse)
24 BITMAPINFO *newInfo;
25 HGLOBAL16 hmem;
26 INT size;
28 if (info->bmiHeader.biCompression)
29 size = info->bmiHeader.biSizeImage;
30 else
31 size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
32 info->bmiHeader.biHeight,
33 info->bmiHeader.biBitCount);
34 size += DIB_BitmapInfoSize( info, coloruse );
36 if (!(hmem = GlobalAlloc16( GMEM_MOVEABLE, size )))
38 return 0;
40 newInfo = (BITMAPINFO *) GlobalLock16( hmem );
41 memcpy( newInfo, info, size );
42 GlobalUnlock16( hmem );
43 return hmem;
48 static BOOL create_brush_indirect(BRUSHOBJ *brushPtr, BOOL v16)
50 LOGBRUSH *brush = &brushPtr->logbrush;
52 switch (brush->lbStyle)
54 case BS_PATTERN8X8:
55 brush->lbStyle = BS_PATTERN;
56 case BS_PATTERN:
57 brush->lbHatch = (LONG)BITMAP_CopyBitmap( (HBITMAP) brush->lbHatch );
58 if (! brush->lbHatch)
59 break;
60 return TRUE;
62 case BS_DIBPATTERNPT:
63 brush->lbStyle = BS_DIBPATTERN;
64 brush->lbHatch = (LONG)dib_copy( (BITMAPINFO *) brush->lbHatch,
65 brush->lbColor);
66 if (! brush->lbHatch)
67 break;
68 return TRUE;
70 case BS_DIBPATTERN8X8:
71 case BS_DIBPATTERN:
73 BITMAPINFO* bmi;
74 HGLOBAL h = brush->lbHatch;
76 brush->lbStyle = BS_DIBPATTERN;
77 if (v16)
79 if (!(bmi = (BITMAPINFO *)GlobalLock16( h )))
80 break;
82 else
84 if (!(bmi = (BITMAPINFO *)GlobalLock( h )))
85 break;
88 brush->lbHatch = dib_copy( bmi, brush->lbColor);
90 if (v16) GlobalUnlock16( h );
91 else GlobalUnlock( h );
93 if (!brush->lbHatch)
94 break;
96 return TRUE;
99 default:
100 if( brush->lbStyle <= BS_MONOPATTERN)
101 return TRUE;
104 return FALSE;
108 /***********************************************************************
109 * CreateBrushIndirect (GDI.50)
111 HBRUSH16 WINAPI CreateBrushIndirect16( const LOGBRUSH16 * brush )
113 BOOL success;
114 BRUSHOBJ * brushPtr;
115 HBRUSH hbrush;
117 if (!(brushPtr = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC, &hbrush ))) return 0;
118 brushPtr->logbrush.lbStyle = brush->lbStyle;
119 brushPtr->logbrush.lbColor = brush->lbColor;
120 brushPtr->logbrush.lbHatch = brush->lbHatch;
121 success = create_brush_indirect(brushPtr, TRUE);
122 if(!success)
124 GDI_FreeObject( hbrush, brushPtr );
125 hbrush = 0;
127 else GDI_ReleaseObj( hbrush );
128 TRACE("%04x\n", hbrush);
129 return hbrush;
133 /***********************************************************************
134 * CreateBrushIndirect (GDI32.@)
136 * BUGS
137 * As for Windows 95 and Windows 98:
138 * Creating brushes from bitmaps or DIBs larger than 8x8 pixels
139 * is not supported. If a larger bitmap is given, only a portion
140 * of the bitmap is used.
142 HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
144 BOOL success;
145 BRUSHOBJ * brushPtr;
146 HBRUSH hbrush;
147 if (!(brushPtr = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC, &hbrush ))) return 0;
148 brushPtr->logbrush.lbStyle = brush->lbStyle;
149 brushPtr->logbrush.lbColor = brush->lbColor;
150 brushPtr->logbrush.lbHatch = brush->lbHatch;
151 success = create_brush_indirect(brushPtr, FALSE);
152 if(!success)
154 GDI_FreeObject( hbrush, brushPtr );
155 hbrush = 0;
157 else GDI_ReleaseObj( hbrush );
158 TRACE("%08x\n", hbrush);
159 return hbrush;
163 /***********************************************************************
164 * CreateHatchBrush (GDI.58)
166 HBRUSH16 WINAPI CreateHatchBrush16( INT16 style, COLORREF color )
168 return CreateHatchBrush( style, color );
172 /***********************************************************************
173 * CreateHatchBrush (GDI32.@)
175 HBRUSH WINAPI CreateHatchBrush( INT style, COLORREF color )
177 LOGBRUSH logbrush;
179 TRACE("%d %06lx\n", style, color );
181 logbrush.lbStyle = BS_HATCHED;
182 logbrush.lbColor = color;
183 logbrush.lbHatch = style;
185 return CreateBrushIndirect( &logbrush );
189 /***********************************************************************
190 * CreatePatternBrush (GDI.60)
192 HBRUSH16 WINAPI CreatePatternBrush16( HBITMAP16 hbitmap )
194 return (HBRUSH16)CreatePatternBrush( hbitmap );
198 /***********************************************************************
199 * CreatePatternBrush (GDI32.@)
201 HBRUSH WINAPI CreatePatternBrush( HBITMAP hbitmap )
203 LOGBRUSH logbrush = { BS_PATTERN, 0, 0 };
204 TRACE("%04x\n", hbitmap );
206 logbrush.lbHatch = hbitmap;
207 return CreateBrushIndirect( &logbrush );
211 /***********************************************************************
212 * CreateDIBPatternBrush (GDI.445)
214 HBRUSH16 WINAPI CreateDIBPatternBrush16( HGLOBAL16 hbitmap, UINT16 coloruse )
216 LOGBRUSH16 logbrush;
218 TRACE("%04x\n", hbitmap );
220 logbrush.lbStyle = BS_DIBPATTERN;
221 logbrush.lbColor = coloruse;
222 logbrush.lbHatch = hbitmap;
224 return CreateBrushIndirect16( &logbrush );
228 /***********************************************************************
229 * CreateDIBPatternBrush (GDI32.@)
231 * Create a logical brush which has the pattern specified by the DIB
233 * Function call is for compatibility only. CreateDIBPatternBrushPt should be used.
235 * RETURNS
237 * Handle to a logical brush on success, NULL on failure.
239 * BUGS
242 HBRUSH WINAPI CreateDIBPatternBrush(
243 HGLOBAL hbitmap, /* [in] Global object containg BITMAPINFO structure */
244 UINT coloruse /* [in] Specifies color format, if provided */
247 LOGBRUSH logbrush;
249 TRACE("%04x\n", hbitmap );
251 logbrush.lbStyle = BS_DIBPATTERN;
252 logbrush.lbColor = coloruse;
254 logbrush.lbHatch = (LONG)hbitmap;
256 return CreateBrushIndirect( &logbrush );
260 /***********************************************************************
261 * CreateDIBPatternBrushPt (GDI32.@)
263 * Create a logical brush which has the pattern specified by the DIB
265 * RETURNS
267 * Handle to a logical brush on success, NULL on failure.
269 * BUGS
272 HBRUSH WINAPI CreateDIBPatternBrushPt(
273 const void* data, /* [in] Pointer to a BITMAPINFO structure followed by more data */
274 UINT coloruse /* [in] Specifies color format, if provided */
277 BITMAPINFO *info=(BITMAPINFO*)data;
278 LOGBRUSH logbrush;
280 TRACE("%p %ldx%ld %dbpp\n", info, info->bmiHeader.biWidth,
281 info->bmiHeader.biHeight, info->bmiHeader.biBitCount);
283 logbrush.lbStyle = BS_DIBPATTERNPT;
284 logbrush.lbColor = coloruse;
285 logbrush.lbHatch = (LONG) data;
287 return CreateBrushIndirect( &logbrush );
291 /***********************************************************************
292 * CreateSolidBrush (GDI.66)
294 HBRUSH16 WINAPI CreateSolidBrush16( COLORREF color )
296 return CreateSolidBrush( color );
300 /***********************************************************************
301 * CreateSolidBrush (GDI32.@)
303 HBRUSH WINAPI CreateSolidBrush( COLORREF color )
305 LOGBRUSH logbrush;
307 TRACE("%06lx\n", color );
309 logbrush.lbStyle = BS_SOLID;
310 logbrush.lbColor = color;
311 logbrush.lbHatch = 0;
313 return CreateBrushIndirect( &logbrush );
317 /***********************************************************************
318 * SetBrushOrg (GDI.148)
320 DWORD WINAPI SetBrushOrg16( HDC16 hdc, INT16 x, INT16 y )
322 DWORD retval;
323 DC *dc = DC_GetDCPtr( hdc );
324 if (!dc) return FALSE;
325 retval = dc->brushOrgX | (dc->brushOrgY << 16);
326 dc->brushOrgX = x;
327 dc->brushOrgY = y;
328 GDI_ReleaseObj( hdc );
329 return retval;
333 /***********************************************************************
334 * SetBrushOrgEx (GDI32.@)
336 BOOL WINAPI SetBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
338 DC *dc = DC_GetDCPtr( hdc );
340 if (!dc) return FALSE;
341 if (oldorg)
343 oldorg->x = dc->brushOrgX;
344 oldorg->y = dc->brushOrgY;
346 dc->brushOrgX = x;
347 dc->brushOrgY = y;
348 GDI_ReleaseObj( hdc );
349 return TRUE;
352 /***********************************************************************
353 * FixBrushOrgEx (GDI32.@)
354 * SDK says discontinued, but in Win95 GDI32 this is the same as SetBrushOrgEx
356 BOOL WINAPI FixBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
358 return SetBrushOrgEx(hdc,x,y,oldorg);
362 /***********************************************************************
363 * BRUSH_DeleteObject
365 BOOL BRUSH_DeleteObject( HBRUSH16 hbrush, BRUSHOBJ * brush )
367 switch(brush->logbrush.lbStyle)
369 case BS_PATTERN:
370 DeleteObject( (HGDIOBJ)brush->logbrush.lbHatch );
371 break;
372 case BS_DIBPATTERN:
373 GlobalFree16( (HGLOBAL16)brush->logbrush.lbHatch );
374 break;
376 return GDI_FreeObject( hbrush, brush );
380 /***********************************************************************
381 * BRUSH_GetObject16
383 INT16 BRUSH_GetObject16( BRUSHOBJ * brush, INT16 count, LPSTR buffer )
385 LOGBRUSH16 logbrush;
387 logbrush.lbStyle = brush->logbrush.lbStyle;
388 logbrush.lbColor = brush->logbrush.lbColor;
389 logbrush.lbHatch = brush->logbrush.lbHatch;
390 if (count > sizeof(logbrush)) count = sizeof(logbrush);
391 memcpy( buffer, &logbrush, count );
392 return count;
396 /***********************************************************************
397 * BRUSH_GetObject
399 INT BRUSH_GetObject( BRUSHOBJ * brush, INT count, LPSTR buffer )
401 if (count > sizeof(brush->logbrush)) count = sizeof(brush->logbrush);
402 memcpy( buffer, &brush->logbrush, count );
403 return count;
407 /***********************************************************************
408 * SetSolidBrush (GDI.604)
410 * If hBrush is a solid brush, change its color to newColor.
412 * RETURNS
413 * TRUE on success, FALSE on failure.
415 * FIXME: untested, not sure if correct.
417 BOOL16 WINAPI SetSolidBrush16(HBRUSH16 hBrush, COLORREF newColor )
419 BRUSHOBJ * brushPtr;
420 BOOL16 res = FALSE;
422 TRACE("(hBrush %04x, newColor %08lx)\n", hBrush, (DWORD)newColor);
423 if (!(brushPtr = (BRUSHOBJ *) GDI_GetObjPtr( hBrush, BRUSH_MAGIC )))
424 return FALSE;
426 if (brushPtr->logbrush.lbStyle == BS_SOLID)
428 brushPtr->logbrush.lbColor = newColor;
429 res = TRUE;
432 GDI_ReleaseObj( hBrush );
433 return res;