Release 980628
[wine/multimedia.git] / objects / gdiobj.c
blobc3ded34b5495562cfd30f08f42327cdbd418780e
1 /*
2 * GDI functions
4 * Copyright 1993 Alexandre Julliard
5 */
7 #include <stdlib.h>
8 #include "color.h"
9 #include "bitmap.h"
10 #include "brush.h"
11 #include "dc.h"
12 #include "font.h"
13 #include "heap.h"
14 #include "options.h"
15 #include "palette.h"
16 #include "pen.h"
17 #include "region.h"
18 #include "debug.h"
19 #include "gdi.h"
22 /***********************************************************************
23 * GDI stock objects
26 static BRUSHOBJ WhiteBrush =
28 { 0, BRUSH_MAGIC, 1 }, /* header */
29 { BS_SOLID, RGB(255,255,255), 0 } /* logbrush */
32 static BRUSHOBJ LtGrayBrush =
34 { 0, BRUSH_MAGIC, 1 }, /* header */
35 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
36 { BS_SOLID, RGB(192,192,192), 0 } /* logbrush */
39 static BRUSHOBJ GrayBrush =
41 { 0, BRUSH_MAGIC, 1 }, /* header */
42 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
43 { BS_SOLID, RGB(128,128,128), 0 } /* logbrush */
46 static BRUSHOBJ DkGrayBrush =
48 { 0, BRUSH_MAGIC, 1 }, /* header */
49 /* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
50 /* NB_HATCH_STYLES is an index into HatchBrushes */
51 { BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES } /* logbrush */
54 static BRUSHOBJ BlackBrush =
56 { 0, BRUSH_MAGIC, 1 }, /* header */
57 { BS_SOLID, RGB(0,0,0), 0 } /* logbrush */
60 static BRUSHOBJ NullBrush =
62 { 0, BRUSH_MAGIC, 1 }, /* header */
63 { BS_NULL, 0, 0 } /* logbrush */
66 static PENOBJ WhitePen =
68 { 0, PEN_MAGIC, 1 }, /* header */
69 { PS_SOLID, { 1, 0 }, RGB(255,255,255) } /* logpen */
72 static PENOBJ BlackPen =
74 { 0, PEN_MAGIC, 1 }, /* header */
75 { PS_SOLID, { 1, 0 }, RGB(0,0,0) } /* logpen */
78 static PENOBJ NullPen =
80 { 0, PEN_MAGIC, 1 }, /* header */
81 { PS_NULL, { 1, 0 }, 0 } /* logpen */
84 static FONTOBJ OEMFixedFont =
86 { 0, FONT_MAGIC, 1 }, /* header */
87 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET,
88 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
90 /* Filler to make the location counter dword aligned again. This is necessary
91 since (a) FONTOBJ is packed, (b) gcc places initialised variables in the code
92 segment, and (c) Solaris assembler is stupid. */
93 static UINT16 align_OEMFixedFont = 1;
95 static FONTOBJ AnsiFixedFont =
97 { 0, FONT_MAGIC, 1 }, /* header */
98 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
99 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
101 static UINT16 align_AnsiFixedFont = 1;
103 static FONTOBJ AnsiVarFont =
105 { 0, FONT_MAGIC, 1 }, /* header */
106 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
107 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
109 static UINT16 align_AnsiVarFont = 1;
111 static FONTOBJ SystemFont =
113 { 0, FONT_MAGIC, 1 },
114 { 16, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
115 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "System" }
117 static UINT16 align_SystemFont = 1;
119 static FONTOBJ DeviceDefaultFont =
121 { 0, FONT_MAGIC, 1 }, /* header */
122 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
123 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "" }
125 static UINT16 align_DeviceDefaultFont = 1;
127 static FONTOBJ SystemFixedFont =
129 { 0, FONT_MAGIC, 1 }, /* header */
130 { 12, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
131 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
133 static UINT16 align_SystemFixedFont = 1;
135 /* FIXME: Is this correct? */
136 static FONTOBJ DefaultGuiFont =
138 { 9, FONT_MAGIC, 1 }, /* header */
139 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
140 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
142 static UINT16 align_DefaultGuiFont = 1;
145 static GDIOBJHDR * StockObjects[NB_STOCK_OBJECTS] =
147 (GDIOBJHDR *) &WhiteBrush,
148 (GDIOBJHDR *) &LtGrayBrush,
149 (GDIOBJHDR *) &GrayBrush,
150 (GDIOBJHDR *) &DkGrayBrush,
151 (GDIOBJHDR *) &BlackBrush,
152 (GDIOBJHDR *) &NullBrush,
153 (GDIOBJHDR *) &WhitePen,
154 (GDIOBJHDR *) &BlackPen,
155 (GDIOBJHDR *) &NullPen,
156 NULL,
157 (GDIOBJHDR *) &OEMFixedFont,
158 (GDIOBJHDR *) &AnsiFixedFont,
159 (GDIOBJHDR *) &AnsiVarFont,
160 (GDIOBJHDR *) &SystemFont,
161 (GDIOBJHDR *) &DeviceDefaultFont,
162 NULL, /* DEFAULT_PALETTE created by PALETTE_Init */
163 (GDIOBJHDR *) &SystemFixedFont,
164 (GDIOBJHDR *) &DefaultGuiFont
167 /******************************************************************************
169 * void ReadFontInformation(
170 * char const *fontName,
171 * FONTOBJ *font,
172 * int defHeight,
173 * int defBold,
174 * int defItalic,
175 * int defUnderline,
176 * int defStrikeOut )
178 * ReadFontInformation() checks the Wine configuration file's Tweak.Fonts
179 * section for entries containing fontName.Height, fontName.Bold, etc.,
180 * where fontName is the name specified in the call (e.g., "System"). It
181 * attempts to be user friendly by accepting 'n', 'N', 'f', 'F', or '0' as
182 * the first character in the boolean attributes (bold, italic, and
183 * underline).
184 *****************************************************************************/
186 static void ReadFontInformation(
187 char const *fontName,
188 FONTOBJ *font,
189 int defHeight,
190 int defBold,
191 int defItalic,
192 int defUnderline,
193 int defStrikeOut )
195 char key[256];
197 sprintf(key, "%s.Height", fontName);
198 font->logfont.lfHeight =
199 PROFILE_GetWineIniInt("Tweak.Fonts", key, defHeight);
201 sprintf(key, "%s.Bold", fontName);
202 font->logfont.lfWeight =
203 (PROFILE_GetWineIniBool("Tweak.Fonts", key, defBold)) ?
204 FW_BOLD : FW_NORMAL;
206 sprintf(key, "%s.Italic", fontName);
207 font->logfont.lfItalic =
208 PROFILE_GetWineIniBool("Tweak.Fonts", key, defItalic);
210 sprintf(key, "%s.Underline", fontName);
211 font->logfont.lfUnderline =
212 PROFILE_GetWineIniBool("Tweak.Fonts", key, defUnderline);
214 sprintf(key, "%s.StrikeOut", fontName);
215 font->logfont.lfStrikeOut =
216 PROFILE_GetWineIniBool("Tweak.Fonts", key, defStrikeOut);
218 return;
222 /***********************************************************************
223 * GDI_Init
225 * GDI initialization.
227 BOOL32 GDI_Init(void)
229 /* Kill some warnings. */
230 (void)align_OEMFixedFont;
231 (void)align_AnsiFixedFont;
232 (void)align_AnsiVarFont;
233 (void)align_SystemFont;
234 (void)align_DeviceDefaultFont;
235 (void)align_SystemFixedFont;
236 (void)align_DefaultGuiFont;
238 /* TWEAK: Initialize font hints */
239 ReadFontInformation("OEMFixed", &OEMFixedFont, 12, 0, 0, 0, 0);
240 ReadFontInformation("AnsiFixed", &AnsiFixedFont, 12, 0, 0, 0, 0);
241 ReadFontInformation("AnsiVar", &AnsiVarFont, 12, 0, 0, 0, 0);
242 ReadFontInformation("System", &SystemFont, 16, 1, 0, 0, 0);
243 ReadFontInformation("SystemFixed", &SystemFixedFont, 12, 1, 0, 0, 0);
245 /* Initialize drivers */
247 DIB_Init(); /* always before X11DRV_Init() */
249 if( ! X11DRV_Init() )
250 return FALSE;
252 /* Create default palette */
254 /* DR well *this* palette can't be moveable (?) */
256 HPALETTE16 hpalette = PALETTE_Init();
257 if( !hpalette )
258 return FALSE;
259 StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)GDI_HEAP_LOCK( hpalette );
262 return TRUE;
266 /***********************************************************************
267 * GDI_AllocObject
269 HGDIOBJ16 GDI_AllocObject( WORD size, WORD magic )
271 static DWORD count = 0;
272 GDIOBJHDR * obj;
273 HGDIOBJ16 handle;
274 if ( magic == DC_MAGIC || magic == METAFILE_DC_MAGIC )
275 handle = GDI_HEAP_ALLOC( size );
276 else
277 handle = GDI_HEAP_ALLOC_MOVEABLE( size );
278 if (!handle) return 0;
279 obj = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
280 obj->hNext = 0;
281 obj->wMagic = magic;
282 obj->dwCount = ++count;
283 GDI_HEAP_UNLOCK( handle );
284 return handle;
288 /***********************************************************************
289 * GDI_FreeObject
291 BOOL32 GDI_FreeObject( HGDIOBJ16 handle )
293 GDIOBJHDR * object;
295 /* Can't free stock objects */
296 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
297 return TRUE;
299 object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
300 if (!object) return FALSE;
301 object->wMagic = 0; /* Mark it as invalid */
303 /* Free object */
305 GDI_HEAP_FREE( handle );
306 return TRUE;
309 /***********************************************************************
310 * GDI_GetObjPtr
312 * Return a pointer to the GDI object associated to the handle.
313 * Return NULL if the object has the wrong magic number.
314 * Movable GDI objects are locked in memory: it is up to the caller to unlock
315 * it after the caller is done with the pointer.
317 GDIOBJHDR * GDI_GetObjPtr( HGDIOBJ16 handle, WORD magic )
319 GDIOBJHDR * ptr = NULL;
321 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
322 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
323 else
324 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
325 if (!ptr) return NULL;
326 if ((magic != MAGIC_DONTCARE) && (ptr->wMagic != magic))
328 GDI_HEAP_UNLOCK( handle );
329 return NULL;
331 return ptr;
335 /***********************************************************************
336 * DeleteObject16 (GDI.69)
338 BOOL16 WINAPI DeleteObject16( HGDIOBJ16 obj )
340 return DeleteObject32( obj );
344 /***********************************************************************
345 * DeleteObject32 (GDI32.70)
347 BOOL32 WINAPI DeleteObject32( HGDIOBJ32 obj )
349 /* Check if object is valid */
351 GDIOBJHDR * header;
352 if (HIWORD(obj)) return FALSE;
353 if ((obj >= FIRST_STOCK_HANDLE) && (obj <= LAST_STOCK_HANDLE))
354 return TRUE;
355 if (!(header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj ))) return FALSE;
357 TRACE(gdi, "%04x\n", obj );
359 /* Delete object */
361 switch(header->wMagic)
363 case PEN_MAGIC: return GDI_FreeObject( obj );
364 case BRUSH_MAGIC: return BRUSH_DeleteObject( obj, (BRUSHOBJ*)header );
365 case FONT_MAGIC: return GDI_FreeObject( obj );
366 case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header);
367 case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header);
368 case REGION_MAGIC: return REGION_DeleteObject( obj, (RGNOBJ*)header );
370 return FALSE;
374 /***********************************************************************
375 * GetStockObject16 (GDI.87)
377 HGDIOBJ16 WINAPI GetStockObject16( INT16 obj )
379 return (HGDIOBJ16)GetStockObject32( obj );
383 /***********************************************************************
384 * GetStockObject32 (GDI32.220)
386 HGDIOBJ32 WINAPI GetStockObject32( INT32 obj )
388 if ((obj < 0) || (obj >= NB_STOCK_OBJECTS)) return 0;
389 if (!StockObjects[obj]) return 0;
390 TRACE(gdi, "returning %d\n",
391 FIRST_STOCK_HANDLE + obj );
392 return (HGDIOBJ16)(FIRST_STOCK_HANDLE + obj);
396 /***********************************************************************
397 * GetObject16 (GDI.82)
399 INT16 WINAPI GetObject16( HANDLE16 handle, INT16 count, LPVOID buffer )
401 GDIOBJHDR * ptr = NULL;
402 INT16 result = 0;
403 TRACE(gdi, "%04x %d %p\n", handle, count, buffer );
404 if (!count) return 0;
406 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
407 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
408 else
409 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
410 if (!ptr) return 0;
412 switch(ptr->wMagic)
414 case PEN_MAGIC:
415 result = PEN_GetObject16( (PENOBJ *)ptr, count, buffer );
416 break;
417 case BRUSH_MAGIC:
418 result = BRUSH_GetObject16( (BRUSHOBJ *)ptr, count, buffer );
419 break;
420 case BITMAP_MAGIC:
421 result = BITMAP_GetObject16( (BITMAPOBJ *)ptr, count, buffer );
422 break;
423 case FONT_MAGIC:
424 result = FONT_GetObject16( (FONTOBJ *)ptr, count, buffer );
425 break;
426 case PALETTE_MAGIC:
427 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
428 break;
430 GDI_HEAP_UNLOCK( handle );
431 return result;
435 /***********************************************************************
436 * GetObject32A (GDI32.204)
438 INT32 WINAPI GetObject32A( HANDLE32 handle, INT32 count, LPVOID buffer )
440 GDIOBJHDR * ptr = NULL;
441 INT32 result = 0;
442 TRACE(gdi, "%08x %d %p\n", handle, count, buffer );
443 if (!count) return 0;
445 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
446 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
447 else
448 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
449 if (!ptr) return 0;
451 switch(ptr->wMagic)
453 case PEN_MAGIC:
454 result = PEN_GetObject32( (PENOBJ *)ptr, count, buffer );
455 break;
456 case BRUSH_MAGIC:
457 result = BRUSH_GetObject32( (BRUSHOBJ *)ptr, count, buffer );
458 break;
459 case BITMAP_MAGIC:
460 result = BITMAP_GetObject32( (BITMAPOBJ *)ptr, count, buffer );
461 break;
462 case FONT_MAGIC:
463 result = FONT_GetObject32A( (FONTOBJ *)ptr, count, buffer );
464 break;
465 case PALETTE_MAGIC:
466 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
467 break;
468 default:
469 FIXME(gdi, "Magic %04x not implemented\n",
470 ptr->wMagic );
471 break;
473 GDI_HEAP_UNLOCK( handle );
474 return result;
477 /***********************************************************************
478 * GetObjectType (GDI32.205)
480 DWORD WINAPI GetObjectType( HANDLE32 handle )
482 GDIOBJHDR * ptr = NULL;
483 INT32 result = 0;
484 TRACE(gdi, "%08x\n", handle );
486 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
487 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
488 else
489 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
490 if (!ptr) return 0;
492 switch(ptr->wMagic)
494 case PEN_MAGIC:
495 result = OBJ_PEN;
496 break;
497 case BRUSH_MAGIC:
498 result = OBJ_BRUSH;
499 break;
500 case BITMAP_MAGIC:
501 result = OBJ_BITMAP;
502 break;
503 case FONT_MAGIC:
504 result = OBJ_FONT;
505 break;
506 case PALETTE_MAGIC:
507 result = OBJ_PAL;
508 break;
509 case REGION_MAGIC:
510 result = OBJ_REGION;
511 break;
512 case DC_MAGIC:
513 result = OBJ_DC;
514 break;
515 case META_DC_MAGIC:
516 result = OBJ_METADC;
517 break;
518 case METAFILE_MAGIC:
519 result = OBJ_METAFILE;
520 break;
521 case METAFILE_DC_MAGIC:
522 result = OBJ_METADC;
523 break;
525 default:
526 FIXME(gdi, "Magic %04x not implemented\n",
527 ptr->wMagic );
528 break;
530 GDI_HEAP_UNLOCK( handle );
531 return result;
534 /***********************************************************************
535 * GetObject32W (GDI32.206)
537 INT32 WINAPI GetObject32W( HANDLE32 handle, INT32 count, LPVOID buffer )
539 return GetObject32A( handle, count, buffer );
542 /***********************************************************************
543 * GetCurrentObject (GDI32.166)
545 HANDLE32 WINAPI GetCurrentObject(HDC32 hdc,UINT32 type)
547 DC * dc = DC_GetDCPtr( hdc );
549 if (!dc)
550 return 0;
551 switch (type) {
552 case OBJ_PEN: return dc->w.hPen;
553 case OBJ_BRUSH: return dc->w.hBrush;
554 case OBJ_PAL: return dc->w.hPalette;
555 case OBJ_FONT: return dc->w.hFont;
556 case OBJ_BITMAP: return dc->w.hBitmap;
557 default:
558 /* the SDK only mentions those above */
559 WARN(gdi,"(%08x,%d): unknown type.\n",hdc,type);
560 return 0;
565 /***********************************************************************
566 * SelectObject16 (GDI.45)
568 HGDIOBJ16 WINAPI SelectObject16( HDC16 hdc, HGDIOBJ16 handle )
570 return (HGDIOBJ16)SelectObject32( hdc, handle );
574 /***********************************************************************
575 * SelectObject32 (GDI32.299)
577 HGDIOBJ32 WINAPI SelectObject32( HDC32 hdc, HGDIOBJ32 handle )
579 DC * dc = DC_GetDCPtr( hdc );
580 if (!dc || !dc->funcs->pSelectObject) return 0;
581 TRACE(gdi, "hdc=%04x %04x\n", hdc, handle );
582 return dc->funcs->pSelectObject( dc, handle );
586 /***********************************************************************
587 * UnrealizeObject16 (GDI.150)
589 BOOL16 WINAPI UnrealizeObject16( HGDIOBJ16 obj )
591 return UnrealizeObject32( obj );
595 /***********************************************************************
596 * UnrealizeObject (GDI32.358)
598 BOOL32 WINAPI UnrealizeObject32( HGDIOBJ32 obj )
600 BOOL32 result = TRUE;
601 /* Check if object is valid */
603 GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj );
604 if (!header) return FALSE;
606 TRACE(gdi, "%04x\n", obj );
608 /* Unrealize object */
610 switch(header->wMagic)
612 case PALETTE_MAGIC:
613 result = PALETTE_UnrealizeObject( obj, (PALETTEOBJ *)header );
614 break;
616 case BRUSH_MAGIC:
617 /* Windows resets the brush origin. We don't need to. */
618 break;
620 GDI_HEAP_UNLOCK( obj );
621 return result;
625 /***********************************************************************
626 * EnumObjects16 (GDI.71)
628 INT16 WINAPI EnumObjects16( HDC16 hdc, INT16 nObjType,
629 GOBJENUMPROC16 lpEnumFunc, LPARAM lParam )
631 /* Solid colors to enumerate */
632 static const COLORREF solid_colors[] =
633 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
634 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
635 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
636 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
637 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
638 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
639 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
640 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
643 INT16 i, retval = 0;
644 LOGPEN16 *pen;
645 LOGBRUSH16 *brush = NULL;
647 TRACE(gdi, "%04x %d %08lx %08lx\n",
648 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
649 switch(nObjType)
651 case OBJ_PEN:
652 /* Enumerate solid pens */
653 if (!(pen = SEGPTR_NEW(LOGPEN16))) break;
654 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
656 pen->lopnStyle = PS_SOLID;
657 pen->lopnWidth.x = 1;
658 pen->lopnWidth.y = 0;
659 pen->lopnColor = solid_colors[i];
660 retval = lpEnumFunc( SEGPTR_GET(pen), lParam );
661 TRACE(gdi, "solid pen %08lx, ret=%d\n",
662 solid_colors[i], retval);
663 if (!retval) break;
665 SEGPTR_FREE(pen);
666 break;
668 case OBJ_BRUSH:
669 /* Enumerate solid brushes */
670 if (!(brush = SEGPTR_NEW(LOGBRUSH16))) break;
671 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
673 brush->lbStyle = BS_SOLID;
674 brush->lbColor = solid_colors[i];
675 brush->lbHatch = 0;
676 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
677 TRACE(gdi, "solid brush %08lx, ret=%d\n",
678 solid_colors[i], retval);
679 if (!retval) break;
682 /* Now enumerate hatched brushes */
683 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
685 brush->lbStyle = BS_HATCHED;
686 brush->lbColor = RGB(0,0,0);
687 brush->lbHatch = i;
688 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
689 TRACE(gdi, "hatched brush %d, ret=%d\n",
690 i, retval);
691 if (!retval) break;
693 SEGPTR_FREE(brush);
694 break;
696 default:
697 WARN(gdi, "(%d): Invalid type\n", nObjType );
698 break;
700 return retval;
704 /***********************************************************************
705 * EnumObjects32 (GDI32.89)
707 INT32 WINAPI EnumObjects32( HDC32 hdc, INT32 nObjType,
708 GOBJENUMPROC32 lpEnumFunc, LPARAM lParam )
710 /* Solid colors to enumerate */
711 static const COLORREF solid_colors[] =
712 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
713 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
714 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
715 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
716 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
717 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
718 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
719 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
722 INT32 i, retval = 0;
723 LOGPEN32 pen;
724 LOGBRUSH32 brush;
726 TRACE(gdi, "%04x %d %08lx %08lx\n",
727 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
728 switch(nObjType)
730 case OBJ_PEN:
731 /* Enumerate solid pens */
732 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
734 pen.lopnStyle = PS_SOLID;
735 pen.lopnWidth.x = 1;
736 pen.lopnWidth.y = 0;
737 pen.lopnColor = solid_colors[i];
738 retval = lpEnumFunc( &pen, lParam );
739 TRACE(gdi, "solid pen %08lx, ret=%d\n",
740 solid_colors[i], retval);
741 if (!retval) break;
743 break;
745 case OBJ_BRUSH:
746 /* Enumerate solid brushes */
747 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
749 brush.lbStyle = BS_SOLID;
750 brush.lbColor = solid_colors[i];
751 brush.lbHatch = 0;
752 retval = lpEnumFunc( &brush, lParam );
753 TRACE(gdi, "solid brush %08lx, ret=%d\n",
754 solid_colors[i], retval);
755 if (!retval) break;
758 /* Now enumerate hatched brushes */
759 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
761 brush.lbStyle = BS_HATCHED;
762 brush.lbColor = RGB(0,0,0);
763 brush.lbHatch = i;
764 retval = lpEnumFunc( &brush, lParam );
765 TRACE(gdi, "hatched brush %d, ret=%d\n",
766 i, retval);
767 if (!retval) break;
769 break;
771 default:
772 /* FIXME: implement Win32 types */
773 WARN( gdi, "(%d): Invalid type\n", nObjType );
774 break;
776 return retval;
780 /***********************************************************************
781 * IsGDIObject (GDI.462)
783 * returns type of object if valid (W95 system programming secrets p. 264-5)
785 BOOL16 WINAPI IsGDIObject( HGDIOBJ16 handle )
787 if (handle >= FIRST_STOCK_HANDLE )
788 return TRUE;
789 else
791 GDIOBJHDR *object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
792 if (object)
794 UINT16 magic = object->wMagic;
795 GDI_HEAP_UNLOCK( handle );
796 if (magic >= PEN_MAGIC && magic <= METAFILE_DC_MAGIC)
797 return magic - PEN_MAGIC + 1;
800 return FALSE;
804 /***********************************************************************
805 * SetObjectOwner16 (GDI.461)
807 void WINAPI SetObjectOwner16( HGDIOBJ16 handle, HANDLE16 owner )
809 /* Nothing to do */
813 /***********************************************************************
814 * SetObjectOwner32 (GDI32.386)
816 void WINAPI SetObjectOwner32( HGDIOBJ32 handle, HANDLE32 owner )
818 /* Nothing to do */
821 /***********************************************************************
822 * GdiFlush (GDI32.128)
824 BOOL32 WINAPI GdiFlush(void)
826 return TRUE; /* FIXME */
830 /***********************************************************************
831 * GdiGetBatchLimit (GDI32.129)
833 DWORD WINAPI GdiGetBatchLimit(void)
835 return 1; /* FIXME */
839 /***********************************************************************
840 * GdiSetBatchLimit (GDI32.139)
842 DWORD WINAPI GdiSetBatchLimit( DWORD limit )
844 return 1; /* FIXME */
848 /***********************************************************************
849 * GdiSeeGdiDo (GDI.452)
851 DWORD WINAPI GdiSeeGdiDo( WORD wReqType, WORD wParam1, WORD wParam2,
852 WORD wParam3 )
854 switch (wReqType)
856 case 0x0001: /* LocalAlloc */
857 return LOCAL_Alloc( GDI_HeapSel, wParam1, wParam3 );
858 case 0x0002: /* LocalFree */
859 return LOCAL_Free( GDI_HeapSel, wParam1 );
860 case 0x0003: /* LocalCompact */
861 return LOCAL_Compact( GDI_HeapSel, wParam3, 0 );
862 case 0x0103: /* LocalHeap */
863 return GDI_HeapSel;
864 default:
865 WARN(gdi, "(wReqType=%04x): Unknown\n", wReqType);
866 return (DWORD)-1;
870 /***********************************************************************
871 * MulDiv16 (GDI.128)
873 INT16 WINAPI MulDiv16( INT16 foo, INT16 bar, INT16 baz )
875 INT32 ret;
876 if (!baz) return -32768;
877 ret = (foo * bar) / baz;
878 if ((ret > 32767) || (ret < -32767)) return -32768;
879 return ret;
883 /***********************************************************************
884 * MulDiv32 (KERNEL32.391)
885 * RETURNS
886 * Result of multiplication and division
887 * -1: Overflow occurred or Divisor was 0
889 INT32 WINAPI MulDiv32(
890 INT32 nMultiplicand,
891 INT32 nMultiplier,
892 INT32 nDivisor
894 #if (SIZEOF_LONG_LONG >= 8)
895 long long ret;
896 if (!nDivisor) return -1;
897 ret = ((long long)nMultiplicand * nMultiplier) / nDivisor;
898 if ((ret > 2147483647) || (ret < -2147483647)) return -1;
899 return ret;
900 #else
901 if (!nDivisor) return -1;
902 return (nMultiplicand * nMultiplier) / nDivisor;
903 #endif