ScrollDC doesn't need to be in the graphics driver.
[wine/multimedia.git] / objects / brush.c
blobcc308ded8d8e0c04be0b9ccac5e35ccdf7644948
1 /*
2 * GDI brush objects
4 * Copyright 1993, 1994 Alexandre Julliard
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "config.h"
23 #include <stdarg.h>
24 #include <string.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "wine/wingdi16.h"
30 #include "bitmap.h"
31 #include "wownt32.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(gdi);
36 /* GDI logical brush object */
37 typedef struct
39 GDIOBJHDR header;
40 LOGBRUSH logbrush;
41 } BRUSHOBJ;
43 #define NB_HATCH_STYLES 6
45 static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
46 static INT BRUSH_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
47 static INT BRUSH_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
48 static BOOL BRUSH_DeleteObject( HGDIOBJ handle, void *obj );
50 static const struct gdi_obj_funcs brush_funcs =
52 BRUSH_SelectObject, /* pSelectObject */
53 BRUSH_GetObject16, /* pGetObject16 */
54 BRUSH_GetObject, /* pGetObjectA */
55 BRUSH_GetObject, /* pGetObjectW */
56 NULL, /* pUnrealizeObject */
57 BRUSH_DeleteObject /* pDeleteObject */
60 static HGLOBAL16 dib_copy(BITMAPINFO *info, UINT coloruse)
62 BITMAPINFO *newInfo;
63 HGLOBAL16 hmem;
64 INT size;
66 if (info->bmiHeader.biCompression)
67 size = info->bmiHeader.biSizeImage;
68 else
69 size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
70 info->bmiHeader.biHeight,
71 info->bmiHeader.biBitCount);
72 size += DIB_BitmapInfoSize( info, coloruse );
74 if (!(hmem = GlobalAlloc16( GMEM_MOVEABLE, size )))
76 return 0;
78 newInfo = (BITMAPINFO *) GlobalLock16( hmem );
79 memcpy( newInfo, info, size );
80 GlobalUnlock16( hmem );
81 return hmem;
85 /***********************************************************************
86 * CreateBrushIndirect (GDI32.@)
88 * BUGS
89 * As for Windows 95 and Windows 98:
90 * Creating brushes from bitmaps or DIBs larger than 8x8 pixels
91 * is not supported. If a larger bitmap is given, only a portion
92 * of the bitmap is used.
94 HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
96 BRUSHOBJ * ptr;
97 HBRUSH hbrush;
99 if (!(ptr = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC,
100 (HGDIOBJ *)&hbrush, &brush_funcs ))) return 0;
101 ptr->logbrush.lbStyle = brush->lbStyle;
102 ptr->logbrush.lbColor = brush->lbColor;
103 ptr->logbrush.lbHatch = brush->lbHatch;
105 switch (ptr->logbrush.lbStyle)
107 case BS_PATTERN8X8:
108 ptr->logbrush.lbStyle = BS_PATTERN;
109 /* fall through */
110 case BS_PATTERN:
111 ptr->logbrush.lbHatch = (LONG)BITMAP_CopyBitmap( (HBITMAP) ptr->logbrush.lbHatch );
112 if (!ptr->logbrush.lbHatch) goto error;
113 break;
115 case BS_DIBPATTERNPT:
116 ptr->logbrush.lbStyle = BS_DIBPATTERN;
117 ptr->logbrush.lbHatch = (LONG)dib_copy( (BITMAPINFO *) ptr->logbrush.lbHatch,
118 ptr->logbrush.lbColor);
119 if (!ptr->logbrush.lbHatch) goto error;
120 break;
122 case BS_DIBPATTERN8X8:
123 case BS_DIBPATTERN:
125 BITMAPINFO* bmi;
126 HGLOBAL h = (HGLOBAL)ptr->logbrush.lbHatch;
128 ptr->logbrush.lbStyle = BS_DIBPATTERN;
129 if (!(bmi = (BITMAPINFO *)GlobalLock( h ))) goto error;
130 ptr->logbrush.lbHatch = dib_copy( bmi, ptr->logbrush.lbColor);
131 GlobalUnlock( h );
132 if (!ptr->logbrush.lbHatch) goto error;
133 break;
136 default:
137 if(ptr->logbrush.lbStyle > BS_MONOPATTERN) goto error;
138 break;
141 GDI_ReleaseObj( hbrush );
142 TRACE("%p\n", hbrush);
143 return hbrush;
145 error:
146 GDI_FreeObject( hbrush, ptr );
147 return 0;
151 /***********************************************************************
152 * CreateHatchBrush (GDI32.@)
154 HBRUSH WINAPI CreateHatchBrush( INT style, COLORREF color )
156 LOGBRUSH logbrush;
158 TRACE("%d %06lx\n", style, color );
160 logbrush.lbStyle = BS_HATCHED;
161 logbrush.lbColor = color;
162 logbrush.lbHatch = style;
164 return CreateBrushIndirect( &logbrush );
168 /***********************************************************************
169 * CreatePatternBrush (GDI32.@)
171 HBRUSH WINAPI CreatePatternBrush( HBITMAP hbitmap )
173 LOGBRUSH logbrush = { BS_PATTERN, 0, 0 };
174 TRACE("%p\n", hbitmap );
176 logbrush.lbHatch = (ULONG_PTR)hbitmap;
177 return CreateBrushIndirect( &logbrush );
181 /***********************************************************************
182 * CreateDIBPatternBrush (GDI32.@)
184 * Create a logical brush which has the pattern specified by the DIB
186 * Function call is for compatibility only. CreateDIBPatternBrushPt should be used.
188 * RETURNS
190 * Handle to a logical brush on success, NULL on failure.
192 * BUGS
195 HBRUSH WINAPI CreateDIBPatternBrush(
196 HGLOBAL hbitmap, /* [in] Global object containg BITMAPINFO structure */
197 UINT coloruse /* [in] Specifies color format, if provided */
200 LOGBRUSH logbrush;
202 TRACE("%p\n", hbitmap );
204 logbrush.lbStyle = BS_DIBPATTERN;
205 logbrush.lbColor = coloruse;
207 logbrush.lbHatch = (LONG)hbitmap;
209 return CreateBrushIndirect( &logbrush );
213 /***********************************************************************
214 * CreateDIBPatternBrushPt (GDI32.@)
216 * Create a logical brush which has the pattern specified by the DIB
218 * RETURNS
220 * Handle to a logical brush on success, NULL on failure.
222 * BUGS
225 HBRUSH WINAPI CreateDIBPatternBrushPt(
226 const void* data, /* [in] Pointer to a BITMAPINFO structure followed by more data */
227 UINT coloruse /* [in] Specifies color format, if provided */
230 BITMAPINFO *info=(BITMAPINFO*)data;
231 LOGBRUSH logbrush;
233 if (!data)
234 return NULL;
236 TRACE("%p %ldx%ld %dbpp\n", info, info->bmiHeader.biWidth,
237 info->bmiHeader.biHeight, info->bmiHeader.biBitCount);
239 logbrush.lbStyle = BS_DIBPATTERNPT;
240 logbrush.lbColor = coloruse;
241 logbrush.lbHatch = (LONG) data;
243 return CreateBrushIndirect( &logbrush );
247 /***********************************************************************
248 * CreateSolidBrush (GDI32.@)
250 HBRUSH WINAPI CreateSolidBrush( COLORREF color )
252 LOGBRUSH logbrush;
254 TRACE("%06lx\n", color );
256 logbrush.lbStyle = BS_SOLID;
257 logbrush.lbColor = color;
258 logbrush.lbHatch = 0;
260 return CreateBrushIndirect( &logbrush );
264 /***********************************************************************
265 * SetBrushOrgEx (GDI32.@)
267 BOOL WINAPI SetBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
269 DC *dc = DC_GetDCPtr( hdc );
271 if (!dc) return FALSE;
272 if (oldorg)
274 oldorg->x = dc->brushOrgX;
275 oldorg->y = dc->brushOrgY;
277 dc->brushOrgX = x;
278 dc->brushOrgY = y;
279 GDI_ReleaseObj( hdc );
280 return TRUE;
283 /***********************************************************************
284 * FixBrushOrgEx (GDI32.@)
285 * SDK says discontinued, but in Win95 GDI32 this is the same as SetBrushOrgEx
287 BOOL WINAPI FixBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
289 return SetBrushOrgEx(hdc,x,y,oldorg);
293 /***********************************************************************
294 * BRUSH_SelectObject
296 static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
298 BRUSHOBJ *brush = obj;
299 HGDIOBJ ret;
300 DC *dc = DC_GetDCPtr( hdc );
302 if (!dc) return 0;
304 if (brush->logbrush.lbStyle == BS_PATTERN)
305 BITMAP_SetOwnerDC( (HBITMAP)brush->logbrush.lbHatch, dc );
307 ret = dc->hBrush;
308 if (dc->funcs->pSelectBrush) handle = dc->funcs->pSelectBrush( dc->physDev, handle );
309 if (handle) dc->hBrush = handle;
310 else ret = 0;
311 GDI_ReleaseObj( hdc );
312 return ret;
316 /***********************************************************************
317 * BRUSH_DeleteObject
319 static BOOL BRUSH_DeleteObject( HGDIOBJ handle, void *obj )
321 BRUSHOBJ *brush = obj;
323 switch(brush->logbrush.lbStyle)
325 case BS_PATTERN:
326 DeleteObject( (HGDIOBJ)brush->logbrush.lbHatch );
327 break;
328 case BS_DIBPATTERN:
329 GlobalFree16( (HGLOBAL16)brush->logbrush.lbHatch );
330 break;
332 return GDI_FreeObject( handle, obj );
336 /***********************************************************************
337 * BRUSH_GetObject16
339 static INT BRUSH_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
341 BRUSHOBJ *brush = obj;
342 LOGBRUSH16 logbrush;
344 logbrush.lbStyle = brush->logbrush.lbStyle;
345 logbrush.lbColor = brush->logbrush.lbColor;
346 logbrush.lbHatch = brush->logbrush.lbHatch;
347 if (count > sizeof(logbrush)) count = sizeof(logbrush);
348 memcpy( buffer, &logbrush, count );
349 return count;
353 /***********************************************************************
354 * BRUSH_GetObject
356 static INT BRUSH_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
358 BRUSHOBJ *brush = obj;
360 if( !buffer )
361 return sizeof(brush->logbrush);
363 if (count > sizeof(brush->logbrush)) count = sizeof(brush->logbrush);
364 memcpy( buffer, &brush->logbrush, count );
365 return count;
369 /***********************************************************************
370 * SetSolidBrush (GDI.604)
372 * If hBrush is a solid brush, change its color to newColor.
374 * RETURNS
375 * TRUE on success, FALSE on failure.
377 * FIXME: untested, not sure if correct.
379 BOOL16 WINAPI SetSolidBrush16(HBRUSH16 hBrush, COLORREF newColor )
381 BRUSHOBJ * brushPtr;
382 BOOL16 res = FALSE;
384 TRACE("(hBrush %04x, newColor %08lx)\n", hBrush, (DWORD)newColor);
385 if (!(brushPtr = (BRUSHOBJ *) GDI_GetObjPtr( HBRUSH_32(hBrush), BRUSH_MAGIC )))
386 return FALSE;
388 if (brushPtr->logbrush.lbStyle == BS_SOLID)
390 brushPtr->logbrush.lbColor = newColor;
391 res = TRUE;
394 GDI_ReleaseObj( HBRUSH_32(hBrush) );
395 return res;