Release 971221
[wine.git] / objects / gdiobj.c
blobfe3c6f959ebad3452a8ba3980ec30277789bb58c
1 /*
2 * GDI functions
4 * Copyright 1993 Alexandre Julliard
5 */
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include "color.h"
10 #include "bitmap.h"
11 #include "brush.h"
12 #include "dc.h"
13 #include "font.h"
14 #include "heap.h"
15 #include "options.h"
16 #include "palette.h"
17 #include "pen.h"
18 #include "region.h"
19 #include "stddebug.h"
20 #include "debug.h"
21 #include "gdi.h"
23 WORD GDI_HeapSel = 0;
25 /***********************************************************************
26 * GDI stock objects
29 static BRUSHOBJ WhiteBrush =
31 { 0, BRUSH_MAGIC, 1 }, /* header */
32 { BS_SOLID, RGB(255,255,255), 0 } /* logbrush */
35 static BRUSHOBJ LtGrayBrush =
37 { 0, BRUSH_MAGIC, 1 }, /* header */
38 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
39 { BS_SOLID, RGB(192,192,192), 0 } /* logbrush */
42 static BRUSHOBJ GrayBrush =
44 { 0, BRUSH_MAGIC, 1 }, /* header */
45 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
46 { BS_SOLID, RGB(128,128,128), 0 } /* logbrush */
49 static BRUSHOBJ DkGrayBrush =
51 { 0, BRUSH_MAGIC, 1 }, /* header */
52 /* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
53 /* NB_HATCH_STYLES is an index into HatchBrushes */
54 { BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES } /* logbrush */
57 static BRUSHOBJ BlackBrush =
59 { 0, BRUSH_MAGIC, 1 }, /* header */
60 { BS_SOLID, RGB(0,0,0), 0 } /* logbrush */
63 static BRUSHOBJ NullBrush =
65 { 0, BRUSH_MAGIC, 1 }, /* header */
66 { BS_NULL, 0, 0 } /* logbrush */
69 static PENOBJ WhitePen =
71 { 0, PEN_MAGIC, 1 }, /* header */
72 { PS_SOLID, { 1, 0 }, RGB(255,255,255) } /* logpen */
75 static PENOBJ BlackPen =
77 { 0, PEN_MAGIC, 1 }, /* header */
78 { PS_SOLID, { 1, 0 }, RGB(0,0,0) } /* logpen */
81 static PENOBJ NullPen =
83 { 0, PEN_MAGIC, 1 }, /* header */
84 { PS_NULL, { 1, 0 }, 0 } /* logpen */
87 static FONTOBJ OEMFixedFont =
89 { 0, FONT_MAGIC, 1 }, /* header */
90 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET,
91 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
93 /* Filler to make the location counter dword aligned again. This is necessary
94 since (a) FONTOBJ is packed, (b) gcc places initialised variables in the code
95 segment, and (c) Solaris assembler is stupid. */
96 static UINT16 align_OEMFixedFont = 1;
98 static FONTOBJ AnsiFixedFont =
100 { 0, FONT_MAGIC, 1 }, /* header */
101 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
102 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
104 static UINT16 align_AnsiFixedFont = 1;
106 static FONTOBJ AnsiVarFont =
108 { 0, FONT_MAGIC, 1 }, /* header */
109 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
110 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
112 static UINT16 align_AnsiVarFont = 1;
114 static FONTOBJ SystemFont =
116 { 0, FONT_MAGIC, 1 },
117 { 16, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
118 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "System" }
120 static UINT16 align_SystemFont = 1;
122 static FONTOBJ DeviceDefaultFont =
124 { 0, FONT_MAGIC, 1 }, /* header */
125 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
126 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "" }
128 static UINT16 align_DeviceDefaultFont = 1;
130 static FONTOBJ SystemFixedFont =
132 { 0, FONT_MAGIC, 1 }, /* header */
133 { 12, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
134 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
136 static UINT16 align_SystemFixedFont = 1;
138 /* FIXME: Is this correct? */
139 static FONTOBJ DefaultGuiFont =
141 { 9, FONT_MAGIC, 1 }, /* header */
142 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
143 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
145 static UINT16 align_DefaultGuiFont = 1;
148 static GDIOBJHDR * StockObjects[NB_STOCK_OBJECTS] =
150 (GDIOBJHDR *) &WhiteBrush,
151 (GDIOBJHDR *) &LtGrayBrush,
152 (GDIOBJHDR *) &GrayBrush,
153 (GDIOBJHDR *) &DkGrayBrush,
154 (GDIOBJHDR *) &BlackBrush,
155 (GDIOBJHDR *) &NullBrush,
156 (GDIOBJHDR *) &WhitePen,
157 (GDIOBJHDR *) &BlackPen,
158 (GDIOBJHDR *) &NullPen,
159 NULL,
160 (GDIOBJHDR *) &OEMFixedFont,
161 (GDIOBJHDR *) &AnsiFixedFont,
162 (GDIOBJHDR *) &AnsiVarFont,
163 (GDIOBJHDR *) &SystemFont,
164 (GDIOBJHDR *) &DeviceDefaultFont,
165 NULL, /* DEFAULT_PALETTE created by PALETTE_Init */
166 (GDIOBJHDR *) &SystemFixedFont,
167 (GDIOBJHDR *) &DefaultGuiFont
170 /******************************************************************************
172 * void ReadFontInformation(
173 * char const *fontName,
174 * FONTOBJ *font,
175 * int defHeight,
176 * int defBold,
177 * int defItalic,
178 * int defUnderline,
179 * int defStrikeOut )
181 * ReadFontInformation() checks the Wine configuration file's Tweak.Fonts
182 * section for entries containing fontName.Height, fontName.Bold, etc.,
183 * where fontName is the name specified in the call (e.g., "System"). It
184 * attempts to be user friendly by accepting 'n', 'N', 'f', 'F', or '0' as
185 * the first character in the boolean attributes (bold, italic, and
186 * underline).
187 *****************************************************************************/
189 static void ReadFontInformation(
190 char const *fontName,
191 FONTOBJ *font,
192 int defHeight,
193 int defBold,
194 int defItalic,
195 int defUnderline,
196 int defStrikeOut )
198 char key[256];
200 sprintf(key, "%s.Height", fontName);
201 font->logfont.lfHeight =
202 PROFILE_GetWineIniInt("Tweak.Fonts", key, defHeight);
204 sprintf(key, "%s.Bold", fontName);
205 font->logfont.lfWeight =
206 (PROFILE_GetWineIniBool("Tweak.Fonts", key, defBold)) ?
207 FW_BOLD : FW_NORMAL;
209 sprintf(key, "%s.Italic", fontName);
210 font->logfont.lfItalic =
211 PROFILE_GetWineIniBool("Tweak.Fonts", key, defItalic);
213 sprintf(key, "%s.Underline", fontName);
214 font->logfont.lfUnderline =
215 PROFILE_GetWineIniBool("Tweak.Fonts", key, defUnderline);
217 sprintf(key, "%s.StrikeOut", fontName);
218 font->logfont.lfStrikeOut =
219 PROFILE_GetWineIniBool("Tweak.Fonts", key, defStrikeOut);
221 return;
225 /***********************************************************************
226 * GDI_Init
228 * GDI initialization.
230 BOOL32 GDI_Init(void)
232 extern BOOL32 X11DRV_Init(void);
233 extern BOOL32 DIB_Init(void);
235 /* Kill some warnings. */
236 (void)align_OEMFixedFont;
237 (void)align_AnsiFixedFont;
238 (void)align_AnsiVarFont;
239 (void)align_SystemFont;
240 (void)align_DeviceDefaultFont;
241 (void)align_SystemFixedFont;
242 (void)align_DefaultGuiFont;
244 /* TWEAK: Initialize font hints */
245 ReadFontInformation("OEMFixed", &OEMFixedFont, 12, 0, 0, 0, 0);
246 ReadFontInformation("AnsiFixed", &AnsiFixedFont, 12, 0, 0, 0, 0);
247 ReadFontInformation("AnsiVar", &AnsiVarFont, 12, 0, 0, 0, 0);
248 ReadFontInformation("System", &SystemFont, 16, 1, 0, 0, 0);
249 ReadFontInformation("SystemFixed", &SystemFixedFont, 12, 1, 0, 0, 0);
251 /* Initialize drivers */
253 DIB_Init(); /* always before X11DRV_Init() */
255 if( X11DRV_Init() )
257 /* Create default palette */
259 /* DR well *this* palette can't be moveable (?) */
261 HPALETTE16 hpalette = PALETTE_Init();
263 if( hpalette )
265 StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)GDI_HEAP_LOCK( hpalette );
266 return TRUE;
269 return FALSE;
273 /***********************************************************************
274 * GDI_AllocObject
276 HGDIOBJ16 GDI_AllocObject( WORD size, WORD magic )
278 static DWORD count = 0;
279 GDIOBJHDR * obj;
280 HGDIOBJ16 handle;
281 if ( magic == DC_MAGIC || magic == METAFILE_DC_MAGIC )
282 handle = GDI_HEAP_ALLOC( size );
283 else
284 handle = GDI_HEAP_ALLOC_MOVEABLE( size );
285 if (!handle) return 0;
286 obj = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
287 obj->hNext = 0;
288 obj->wMagic = magic;
289 obj->dwCount = ++count;
290 GDI_HEAP_UNLOCK( handle );
291 return handle;
295 /***********************************************************************
296 * GDI_FreeObject
298 BOOL32 GDI_FreeObject( HGDIOBJ16 handle )
300 GDIOBJHDR * object;
302 /* Can't free stock objects */
303 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
304 return TRUE;
306 object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
307 if (!object) return FALSE;
308 object->wMagic = 0; /* Mark it as invalid */
310 /* Free object */
312 GDI_HEAP_FREE( handle );
313 return TRUE;
316 /***********************************************************************
317 * GDI_GetObjPtr
319 * Return a pointer to the GDI object associated to the handle.
320 * Return NULL if the object has the wrong magic number.
321 * Movable GDI objects are locked in memory: it is up to the caller to unlock
322 * it after the caller is done with the pointer.
324 GDIOBJHDR * GDI_GetObjPtr( HGDIOBJ16 handle, WORD magic )
326 GDIOBJHDR * ptr = NULL;
328 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
329 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
330 else
331 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
332 if (!ptr) return NULL;
333 if ((magic != MAGIC_DONTCARE) && (ptr->wMagic != magic))
335 GDI_HEAP_UNLOCK( handle );
336 return NULL;
338 return ptr;
342 /***********************************************************************
343 * DeleteObject16 (GDI.69)
345 BOOL16 WINAPI DeleteObject16( HGDIOBJ16 obj )
347 return DeleteObject32( obj );
351 /***********************************************************************
352 * DeleteObject32 (GDI32.70)
354 BOOL32 WINAPI DeleteObject32( HGDIOBJ32 obj )
356 /* Check if object is valid */
358 GDIOBJHDR * header;
359 if (HIWORD(obj)) return FALSE;
360 if ((obj >= FIRST_STOCK_HANDLE) && (obj <= LAST_STOCK_HANDLE))
361 return TRUE;
362 if (!(header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj ))) return FALSE;
364 dprintf_gdi(stddeb, "DeleteObject: %04x\n", obj );
366 /* Delete object */
368 switch(header->wMagic)
370 case PEN_MAGIC: return GDI_FreeObject( obj );
371 case BRUSH_MAGIC: return BRUSH_DeleteObject( obj, (BRUSHOBJ*)header );
372 case FONT_MAGIC: return GDI_FreeObject( obj );
373 case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header);
374 case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header);
375 case REGION_MAGIC: return REGION_DeleteObject( obj, (RGNOBJ*)header );
377 return FALSE;
381 /***********************************************************************
382 * GetStockObject16 (GDI.87)
384 HGDIOBJ16 WINAPI GetStockObject16( INT16 obj )
386 return (HGDIOBJ16)GetStockObject32( obj );
390 /***********************************************************************
391 * GetStockObject32 (GDI32.220)
393 HGDIOBJ32 WINAPI GetStockObject32( INT32 obj )
395 if ((obj < 0) || (obj >= NB_STOCK_OBJECTS)) return 0;
396 if (!StockObjects[obj]) return 0;
397 dprintf_gdi(stddeb, "GetStockObject: returning %d\n",
398 FIRST_STOCK_HANDLE + obj );
399 return (HGDIOBJ16)(FIRST_STOCK_HANDLE + obj);
403 /***********************************************************************
404 * GetObject16 (GDI.82)
406 INT16 WINAPI GetObject16( HANDLE16 handle, INT16 count, LPVOID buffer )
408 GDIOBJHDR * ptr = NULL;
409 INT16 result = 0;
410 dprintf_gdi(stddeb, "GetObject16: %04x %d %p\n", handle, count, buffer );
411 if (!count) return 0;
413 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
414 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
415 else
416 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
417 if (!ptr) return 0;
419 switch(ptr->wMagic)
421 case PEN_MAGIC:
422 result = PEN_GetObject16( (PENOBJ *)ptr, count, buffer );
423 break;
424 case BRUSH_MAGIC:
425 result = BRUSH_GetObject16( (BRUSHOBJ *)ptr, count, buffer );
426 break;
427 case BITMAP_MAGIC:
428 result = BITMAP_GetObject16( (BITMAPOBJ *)ptr, count, buffer );
429 break;
430 case FONT_MAGIC:
431 result = FONT_GetObject16( (FONTOBJ *)ptr, count, buffer );
432 break;
433 case PALETTE_MAGIC:
434 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
435 break;
437 GDI_HEAP_UNLOCK( handle );
438 return result;
442 /***********************************************************************
443 * GetObject32A (GDI32.204)
445 INT32 WINAPI GetObject32A( HANDLE32 handle, INT32 count, LPVOID buffer )
447 GDIOBJHDR * ptr = NULL;
448 INT32 result = 0;
449 dprintf_gdi(stddeb, "GetObject32A: %08x %d %p\n", handle, count, buffer );
450 if (!count) return 0;
452 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
453 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
454 else
455 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
456 if (!ptr) return 0;
458 switch(ptr->wMagic)
460 case PEN_MAGIC:
461 result = PEN_GetObject32( (PENOBJ *)ptr, count, buffer );
462 break;
463 case BRUSH_MAGIC:
464 result = BRUSH_GetObject32( (BRUSHOBJ *)ptr, count, buffer );
465 break;
466 case BITMAP_MAGIC:
467 result = BITMAP_GetObject32( (BITMAPOBJ *)ptr, count, buffer );
468 break;
469 case FONT_MAGIC:
470 result = FONT_GetObject32A( (FONTOBJ *)ptr, count, buffer );
471 break;
472 case PALETTE_MAGIC:
473 fprintf( stderr, "GetObject32: magic %04x not implemented\n",
474 ptr->wMagic );
475 break;
477 GDI_HEAP_UNLOCK( handle );
478 return result;
481 /***********************************************************************
482 * GetObjectType (GDI32.205)
484 DWORD WINAPI GetObjectType( HANDLE32 handle )
486 GDIOBJHDR * ptr = NULL;
487 INT32 result = 0;
488 dprintf_gdi(stddeb, "GetObjectType: %08x\n", handle );
490 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
491 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
492 else
493 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
494 if (!ptr) return 0;
496 switch(ptr->wMagic)
498 case PEN_MAGIC:
499 result = OBJ_PEN;
500 break;
501 case BRUSH_MAGIC:
502 result = OBJ_BRUSH;
503 break;
504 case BITMAP_MAGIC:
505 result = OBJ_BITMAP;
506 break;
507 case FONT_MAGIC:
508 result = OBJ_FONT;
509 break;
510 case PALETTE_MAGIC:
511 result = OBJ_PAL;
512 break;
513 case REGION_MAGIC:
514 result = OBJ_REGION;
515 break;
516 case DC_MAGIC:
517 result = OBJ_DC;
518 break;
519 case META_DC_MAGIC:
520 result = OBJ_METADC;
521 break;
522 case METAFILE_MAGIC:
523 result = OBJ_METAFILE;
524 break;
525 case METAFILE_DC_MAGIC:
526 result = OBJ_METADC;
527 break;
529 default:
530 fprintf( stderr, "GetObjectType: magic %04x not implemented\n",
531 ptr->wMagic );
532 break;
534 GDI_HEAP_UNLOCK( handle );
535 return result;
538 /***********************************************************************
539 * GetObject32W (GDI32.206)
541 INT32 WINAPI GetObject32W( HANDLE32 handle, INT32 count, LPVOID buffer )
543 return GetObject32A( handle, count, buffer );
546 /***********************************************************************
547 * GetCurrentObject (GDI32.166)
549 HANDLE32 WINAPI GetCurrentObject(HDC32 hdc,UINT32 type)
551 DC * dc = DC_GetDCPtr( hdc );
553 if (!dc)
554 return 0;
555 switch (type) {
556 case OBJ_PEN: return dc->w.hPen;
557 case OBJ_BRUSH: return dc->w.hBrush;
558 case OBJ_PAL: return dc->w.hPalette;
559 case OBJ_FONT: return dc->w.hFont;
560 case OBJ_BITMAP: return dc->w.hBitmap;
561 default:
562 /* the SDK only mentions those above */
563 fprintf(stderr,"GetCurrentObject(%08x,%d), unknown type.\n",hdc,type);
564 return 0;
569 /***********************************************************************
570 * SelectObject16 (GDI.45)
572 HGDIOBJ16 WINAPI SelectObject16( HDC16 hdc, HGDIOBJ16 handle )
574 return (HGDIOBJ16)SelectObject32( hdc, handle );
578 /***********************************************************************
579 * SelectObject32 (GDI32.299)
581 HGDIOBJ32 WINAPI SelectObject32( HDC32 hdc, HGDIOBJ32 handle )
583 DC * dc = DC_GetDCPtr( hdc );
584 if (!dc || !dc->funcs->pSelectObject) return 0;
585 dprintf_gdi(stddeb, "SelectObject: hdc=%04x %04x\n", hdc, handle );
586 return dc->funcs->pSelectObject( dc, handle );
590 /***********************************************************************
591 * UnrealizeObject16 (GDI.150)
593 BOOL16 WINAPI UnrealizeObject16( HGDIOBJ16 obj )
595 return UnrealizeObject32( obj );
599 /***********************************************************************
600 * UnrealizeObject (GDI32.358)
602 BOOL32 WINAPI UnrealizeObject32( HGDIOBJ32 obj )
604 BOOL32 result = TRUE;
605 /* Check if object is valid */
607 GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj );
608 if (!header) return FALSE;
610 dprintf_gdi( stddeb, "UnrealizeObject: %04x\n", obj );
612 /* Unrealize object */
614 switch(header->wMagic)
616 case PALETTE_MAGIC:
617 result = PALETTE_UnrealizeObject( obj, (PALETTEOBJ *)header );
618 break;
620 case BRUSH_MAGIC:
621 /* Windows resets the brush origin. We don't need to. */
622 break;
624 GDI_HEAP_UNLOCK( obj );
625 return result;
629 /***********************************************************************
630 * EnumObjects16 (GDI.71)
632 INT16 WINAPI EnumObjects16( HDC16 hdc, INT16 nObjType,
633 GOBJENUMPROC16 lpEnumFunc, LPARAM lParam )
635 /* Solid colors to enumerate */
636 static const COLORREF solid_colors[] =
637 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
638 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
639 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
640 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
641 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
642 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
643 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
644 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
647 INT16 i, retval = 0;
648 LOGPEN16 *pen;
649 LOGBRUSH16 *brush = NULL;
651 dprintf_gdi( stddeb, "EnumObjects16: %04x %d %08lx %08lx\n",
652 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
653 switch(nObjType)
655 case OBJ_PEN:
656 /* Enumerate solid pens */
657 if (!(pen = SEGPTR_NEW(LOGPEN16))) break;
658 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
660 pen->lopnStyle = PS_SOLID;
661 pen->lopnWidth.x = 1;
662 pen->lopnWidth.y = 0;
663 pen->lopnColor = solid_colors[i];
664 retval = lpEnumFunc( SEGPTR_GET(pen), lParam );
665 dprintf_gdi( stddeb, "EnumObjects16: solid pen %08lx, ret=%d\n",
666 solid_colors[i], retval);
667 if (!retval) break;
669 SEGPTR_FREE(pen);
670 break;
672 case OBJ_BRUSH:
673 /* Enumerate solid brushes */
674 if (!(brush = SEGPTR_NEW(LOGBRUSH16))) break;
675 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
677 brush->lbStyle = BS_SOLID;
678 brush->lbColor = solid_colors[i];
679 brush->lbHatch = 0;
680 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
681 dprintf_gdi( stddeb, "EnumObjects16: solid brush %08lx, ret=%d\n",
682 solid_colors[i], retval);
683 if (!retval) break;
686 /* Now enumerate hatched brushes */
687 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
689 brush->lbStyle = BS_HATCHED;
690 brush->lbColor = RGB(0,0,0);
691 brush->lbHatch = i;
692 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
693 dprintf_gdi( stddeb, "EnumObjects16: hatched brush %d, ret=%d\n",
694 i, retval);
695 if (!retval) break;
697 SEGPTR_FREE(brush);
698 break;
700 default:
701 fprintf( stderr, "EnumObjects16: invalid type %d\n", nObjType );
702 break;
704 return retval;
708 /***********************************************************************
709 * EnumObjects32 (GDI32.89)
711 INT32 WINAPI EnumObjects32( HDC32 hdc, INT32 nObjType,
712 GOBJENUMPROC32 lpEnumFunc, LPARAM lParam )
714 /* Solid colors to enumerate */
715 static const COLORREF solid_colors[] =
716 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
717 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
718 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
719 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
720 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
721 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
722 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
723 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
726 INT32 i, retval = 0;
727 LOGPEN32 pen;
728 LOGBRUSH32 brush;
730 dprintf_gdi( stddeb, "EnumObjects32: %04x %d %08lx %08lx\n",
731 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
732 switch(nObjType)
734 case OBJ_PEN:
735 /* Enumerate solid pens */
736 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
738 pen.lopnStyle = PS_SOLID;
739 pen.lopnWidth.x = 1;
740 pen.lopnWidth.y = 0;
741 pen.lopnColor = solid_colors[i];
742 retval = lpEnumFunc( &pen, lParam );
743 dprintf_gdi( stddeb, "EnumObjects32: solid pen %08lx, ret=%d\n",
744 solid_colors[i], retval);
745 if (!retval) break;
747 break;
749 case OBJ_BRUSH:
750 /* Enumerate solid brushes */
751 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
753 brush.lbStyle = BS_SOLID;
754 brush.lbColor = solid_colors[i];
755 brush.lbHatch = 0;
756 retval = lpEnumFunc( &brush, lParam );
757 dprintf_gdi( stddeb, "EnumObjects32: solid brush %08lx, ret=%d\n",
758 solid_colors[i], retval);
759 if (!retval) break;
762 /* Now enumerate hatched brushes */
763 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
765 brush.lbStyle = BS_HATCHED;
766 brush.lbColor = RGB(0,0,0);
767 brush.lbHatch = i;
768 retval = lpEnumFunc( &brush, lParam );
769 dprintf_gdi( stddeb, "EnumObjects32: hatched brush %d, ret=%d\n",
770 i, retval);
771 if (!retval) break;
773 break;
775 default:
776 /* FIXME: implement Win32 types */
777 fprintf( stderr, "EnumObjects32: invalid type %d\n", nObjType );
778 break;
780 return retval;
784 /***********************************************************************
785 * IsGDIObject (GDI.462)
787 * returns type of object if valid (W95 system programming secrets p. 264-5)
789 BOOL16 WINAPI IsGDIObject( HGDIOBJ16 handle )
791 if (handle >= FIRST_STOCK_HANDLE )
792 return TRUE;
793 else
795 GDIOBJHDR *object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
796 if (object)
798 UINT16 magic = object->wMagic;
799 GDI_HEAP_UNLOCK( handle );
800 if (magic >= PEN_MAGIC && magic <= METAFILE_DC_MAGIC)
801 return magic - PEN_MAGIC + 1;
804 return FALSE;
808 /***********************************************************************
809 * SetObjectOwner16 (GDI.461)
811 void WINAPI SetObjectOwner16( HGDIOBJ16 handle, HANDLE16 owner )
813 /* Nothing to do */
817 /***********************************************************************
818 * SetObjectOwner32 (GDI32.386)
820 void WINAPI SetObjectOwner32( HGDIOBJ32 handle, HANDLE32 owner )
822 /* Nothing to do */
825 /***********************************************************************
826 * GdiFlush (GDI32.128)
828 BOOL32 WINAPI GdiFlush(void)
830 return TRUE; /* FIXME */
834 /***********************************************************************
835 * GdiGetBatchLimit (GDI32.129)
837 DWORD WINAPI GdiGetBatchLimit(void)
839 return 1; /* FIXME */
843 /***********************************************************************
844 * GdiSetBatchLimit (GDI32.139)
846 DWORD WINAPI GdiSetBatchLimit( DWORD limit )
848 return 1; /* FIXME */
852 /***********************************************************************
853 * MulDiv16 (GDI.128)
855 INT16 WINAPI MulDiv16( INT16 foo, INT16 bar, INT16 baz )
857 INT32 ret;
858 if (!baz) return -32768;
859 ret = (foo * bar) / baz;
860 if ((ret > 32767) || (ret < -32767)) return -32768;
861 return ret;
865 /***********************************************************************
866 * MulDiv32 (KERNEL32.391)
868 INT32 WINAPI MulDiv32( INT32 foo, INT32 bar, INT32 baz )
870 #ifdef __GNUC__
871 long long ret;
872 if (!baz) return -1;
873 ret = ((long long)foo * bar) / baz;
874 if ((ret > 2147483647) || (ret < -2147483647)) return -1;
875 return ret;
876 #else
877 if (!baz) return -1;
878 return (foo * bar) / baz;
879 #endif