Getting strings with VerQueryValue32W was broken. Complete
[wine/multimedia.git] / objects / gdiobj.c
blobfd22bdfad1972f97406b88508bf79f3d00ffcad7
1 /*
2 * GDI functions
4 * Copyright 1993 Alexandre Julliard
5 */
7 #include <stdlib.h>
8 #include "bitmap.h"
9 #include "brush.h"
10 #include "dc.h"
11 #include "font.h"
12 #include "heap.h"
13 #include "options.h"
14 #include "palette.h"
15 #include "pen.h"
16 #include "region.h"
17 #include "debug.h"
18 #include "gdi.h"
19 #include "x11drv.h"
21 /***********************************************************************
22 * GDI stock objects
25 static BRUSHOBJ WhiteBrush =
27 { 0, BRUSH_MAGIC, 1 }, /* header */
28 { BS_SOLID, RGB(255,255,255), 0 } /* logbrush */
31 static BRUSHOBJ LtGrayBrush =
33 { 0, BRUSH_MAGIC, 1 }, /* header */
34 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
35 { BS_SOLID, RGB(192,192,192), 0 } /* logbrush */
38 static BRUSHOBJ GrayBrush =
40 { 0, BRUSH_MAGIC, 1 }, /* header */
41 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
42 { BS_SOLID, RGB(128,128,128), 0 } /* logbrush */
45 static BRUSHOBJ DkGrayBrush =
47 { 0, BRUSH_MAGIC, 1 }, /* header */
48 /* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
49 /* NB_HATCH_STYLES is an index into HatchBrushes */
50 { BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES } /* logbrush */
53 static BRUSHOBJ BlackBrush =
55 { 0, BRUSH_MAGIC, 1 }, /* header */
56 { BS_SOLID, RGB(0,0,0), 0 } /* logbrush */
59 static BRUSHOBJ NullBrush =
61 { 0, BRUSH_MAGIC, 1 }, /* header */
62 { BS_NULL, 0, 0 } /* logbrush */
65 static PENOBJ WhitePen =
67 { 0, PEN_MAGIC, 1 }, /* header */
68 { PS_SOLID, { 1, 0 }, RGB(255,255,255) } /* logpen */
71 static PENOBJ BlackPen =
73 { 0, PEN_MAGIC, 1 }, /* header */
74 { PS_SOLID, { 1, 0 }, RGB(0,0,0) } /* logpen */
77 static PENOBJ NullPen =
79 { 0, PEN_MAGIC, 1 }, /* header */
80 { PS_NULL, { 1, 0 }, 0 } /* logpen */
83 static FONTOBJ OEMFixedFont =
85 { 0, FONT_MAGIC, 1 }, /* header */
86 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET,
87 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
89 /* Filler to make the location counter dword aligned again. This is necessary
90 since (a) FONTOBJ is packed, (b) gcc places initialised variables in the code
91 segment, and (c) Solaris assembler is stupid. */
92 static UINT16 align_OEMFixedFont = 1;
94 static FONTOBJ AnsiFixedFont =
96 { 0, FONT_MAGIC, 1 }, /* header */
97 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
98 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
100 static UINT16 align_AnsiFixedFont = 1;
102 static FONTOBJ AnsiVarFont =
104 { 0, FONT_MAGIC, 1 }, /* header */
105 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
106 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
108 static UINT16 align_AnsiVarFont = 1;
110 static FONTOBJ SystemFont =
112 { 0, FONT_MAGIC, 1 },
113 { 16, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
114 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "System" }
116 static UINT16 align_SystemFont = 1;
118 static FONTOBJ DeviceDefaultFont =
120 { 0, FONT_MAGIC, 1 }, /* header */
121 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
122 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "" }
124 static UINT16 align_DeviceDefaultFont = 1;
126 static FONTOBJ SystemFixedFont =
128 { 0, FONT_MAGIC, 1 }, /* header */
129 { 12, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
130 0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
132 static UINT16 align_SystemFixedFont = 1;
134 /* FIXME: Is this correct? */
135 static FONTOBJ DefaultGuiFont =
137 { 9, FONT_MAGIC, 1 }, /* header */
138 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
139 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
141 static UINT16 align_DefaultGuiFont = 1;
144 static GDIOBJHDR * StockObjects[NB_STOCK_OBJECTS] =
146 (GDIOBJHDR *) &WhiteBrush,
147 (GDIOBJHDR *) &LtGrayBrush,
148 (GDIOBJHDR *) &GrayBrush,
149 (GDIOBJHDR *) &DkGrayBrush,
150 (GDIOBJHDR *) &BlackBrush,
151 (GDIOBJHDR *) &NullBrush,
152 (GDIOBJHDR *) &WhitePen,
153 (GDIOBJHDR *) &BlackPen,
154 (GDIOBJHDR *) &NullPen,
155 NULL,
156 (GDIOBJHDR *) &OEMFixedFont,
157 (GDIOBJHDR *) &AnsiFixedFont,
158 (GDIOBJHDR *) &AnsiVarFont,
159 (GDIOBJHDR *) &SystemFont,
160 (GDIOBJHDR *) &DeviceDefaultFont,
161 NULL, /* DEFAULT_PALETTE created by PALETTE_Init */
162 (GDIOBJHDR *) &SystemFixedFont,
163 (GDIOBJHDR *) &DefaultGuiFont
166 /******************************************************************************
168 * void ReadFontInformation(
169 * char const *fontName,
170 * FONTOBJ *font,
171 * int defHeight,
172 * int defBold,
173 * int defItalic,
174 * int defUnderline,
175 * int defStrikeOut )
177 * ReadFontInformation() checks the Wine configuration file's Tweak.Fonts
178 * section for entries containing fontName.Height, fontName.Bold, etc.,
179 * where fontName is the name specified in the call (e.g., "System"). It
180 * attempts to be user friendly by accepting 'n', 'N', 'f', 'F', or '0' as
181 * the first character in the boolean attributes (bold, italic, and
182 * underline).
183 *****************************************************************************/
185 static void ReadFontInformation(
186 char const *fontName,
187 FONTOBJ *font,
188 int defHeight,
189 int defBold,
190 int defItalic,
191 int defUnderline,
192 int defStrikeOut )
194 char key[256];
196 sprintf(key, "%s.Height", fontName);
197 font->logfont.lfHeight =
198 PROFILE_GetWineIniInt("Tweak.Fonts", key, defHeight);
200 sprintf(key, "%s.Bold", fontName);
201 font->logfont.lfWeight =
202 (PROFILE_GetWineIniBool("Tweak.Fonts", key, defBold)) ?
203 FW_BOLD : FW_NORMAL;
205 sprintf(key, "%s.Italic", fontName);
206 font->logfont.lfItalic =
207 PROFILE_GetWineIniBool("Tweak.Fonts", key, defItalic);
209 sprintf(key, "%s.Underline", fontName);
210 font->logfont.lfUnderline =
211 PROFILE_GetWineIniBool("Tweak.Fonts", key, defUnderline);
213 sprintf(key, "%s.StrikeOut", fontName);
214 font->logfont.lfStrikeOut =
215 PROFILE_GetWineIniBool("Tweak.Fonts", key, defStrikeOut);
217 return;
221 /***********************************************************************
222 * GDI_Init
224 * GDI initialization.
226 BOOL32 GDI_Init(void)
228 /* Kill some warnings. */
229 (void)align_OEMFixedFont;
230 (void)align_AnsiFixedFont;
231 (void)align_AnsiVarFont;
232 (void)align_SystemFont;
233 (void)align_DeviceDefaultFont;
234 (void)align_SystemFixedFont;
235 (void)align_DefaultGuiFont;
237 /* TWEAK: Initialize font hints */
238 ReadFontInformation("OEMFixed", &OEMFixedFont, 12, 0, 0, 0, 0);
239 ReadFontInformation("AnsiFixed", &AnsiFixedFont, 12, 0, 0, 0, 0);
240 ReadFontInformation("AnsiVar", &AnsiVarFont, 12, 0, 0, 0, 0);
241 ReadFontInformation("System", &SystemFont, 16, 1, 0, 0, 0);
242 ReadFontInformation("SystemFixed", &SystemFixedFont, 12, 1, 0, 0, 0);
244 /* Initialize drivers */
246 if( ! X11DRV_Init() )
247 return FALSE;
249 /* Create default palette */
251 /* DR well *this* palette can't be moveable (?) */
253 HPALETTE16 hpalette = PALETTE_Init();
254 if( !hpalette )
255 return FALSE;
256 StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *)GDI_HEAP_LOCK( hpalette );
259 return TRUE;
263 /***********************************************************************
264 * GDI_AllocObject
266 HGDIOBJ16 GDI_AllocObject( WORD size, WORD magic )
268 static DWORD count = 0;
269 GDIOBJHDR * obj;
270 HGDIOBJ16 handle;
271 if ( magic == DC_MAGIC || magic == METAFILE_DC_MAGIC )
272 handle = GDI_HEAP_ALLOC( size );
273 else
274 handle = GDI_HEAP_ALLOC_MOVEABLE( size );
275 if (!handle) return 0;
276 obj = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
277 obj->hNext = 0;
278 obj->wMagic = magic;
279 obj->dwCount = ++count;
280 GDI_HEAP_UNLOCK( handle );
281 return handle;
285 /***********************************************************************
286 * GDI_FreeObject
288 BOOL32 GDI_FreeObject( HGDIOBJ16 handle )
290 GDIOBJHDR * object;
292 /* Can't free stock objects */
293 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
294 return TRUE;
296 object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
297 if (!object) return FALSE;
298 object->wMagic = 0; /* Mark it as invalid */
300 /* Free object */
302 GDI_HEAP_FREE( handle );
303 return TRUE;
306 /***********************************************************************
307 * GDI_GetObjPtr
309 * Return a pointer to the GDI object associated to the handle.
310 * Return NULL if the object has the wrong magic number.
311 * Movable GDI objects are locked in memory: it is up to the caller to unlock
312 * it after the caller is done with the pointer.
314 GDIOBJHDR * GDI_GetObjPtr( HGDIOBJ16 handle, WORD magic )
316 GDIOBJHDR * ptr = NULL;
318 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
319 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
320 else
321 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
322 if (!ptr) return NULL;
323 if ((magic != MAGIC_DONTCARE) && (ptr->wMagic != magic))
325 GDI_HEAP_UNLOCK( handle );
326 return NULL;
328 return ptr;
332 /***********************************************************************
333 * DeleteObject16 (GDI.69)
335 BOOL16 WINAPI DeleteObject16( HGDIOBJ16 obj )
337 return DeleteObject32( obj );
341 /***********************************************************************
342 * DeleteObject32 (GDI32.70)
344 BOOL32 WINAPI DeleteObject32( HGDIOBJ32 obj )
346 /* Check if object is valid */
348 GDIOBJHDR * header;
349 if (HIWORD(obj)) return FALSE;
350 if ((obj >= FIRST_STOCK_HANDLE) && (obj <= LAST_STOCK_HANDLE))
351 return TRUE;
352 if (!(header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj ))) return FALSE;
354 TRACE(gdi, "%04x\n", obj );
356 /* Delete object */
358 switch(header->wMagic)
360 case PEN_MAGIC: return GDI_FreeObject( obj );
361 case BRUSH_MAGIC: return BRUSH_DeleteObject( obj, (BRUSHOBJ*)header );
362 case FONT_MAGIC: return GDI_FreeObject( obj );
363 case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header);
364 case BITMAP_MAGIC: return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header);
365 case REGION_MAGIC: return REGION_DeleteObject( obj, (RGNOBJ*)header );
366 case DC_MAGIC: return DeleteDC32(obj);
367 case 0 :
368 WARN(gdi, "Already deleted\n");
369 break;
370 default:
371 WARN(gdi, "Unknown magic number (%d)\n",header->wMagic);
373 return FALSE;
376 /***********************************************************************
377 * GetStockObject16 (GDI.87)
379 HGDIOBJ16 WINAPI GetStockObject16( INT16 obj )
381 return (HGDIOBJ16)GetStockObject32( obj );
385 /***********************************************************************
386 * GetStockObject32 (GDI32.220)
388 HGDIOBJ32 WINAPI GetStockObject32( INT32 obj )
390 if ((obj < 0) || (obj >= NB_STOCK_OBJECTS)) return 0;
391 if (!StockObjects[obj]) return 0;
392 TRACE(gdi, "returning %d\n",
393 FIRST_STOCK_HANDLE + obj );
394 return (HGDIOBJ16)(FIRST_STOCK_HANDLE + obj);
398 /***********************************************************************
399 * GetObject16 (GDI.82)
401 INT16 WINAPI GetObject16( HANDLE16 handle, INT16 count, LPVOID buffer )
403 GDIOBJHDR * ptr = NULL;
404 INT16 result = 0;
405 TRACE(gdi, "%04x %d %p\n", handle, count, buffer );
406 if (!count) return 0;
408 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
409 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
410 else
411 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
412 if (!ptr) return 0;
414 switch(ptr->wMagic)
416 case PEN_MAGIC:
417 result = PEN_GetObject16( (PENOBJ *)ptr, count, buffer );
418 break;
419 case BRUSH_MAGIC:
420 result = BRUSH_GetObject16( (BRUSHOBJ *)ptr, count, buffer );
421 break;
422 case BITMAP_MAGIC:
423 result = BITMAP_GetObject16( (BITMAPOBJ *)ptr, count, buffer );
424 break;
425 case FONT_MAGIC:
426 result = FONT_GetObject16( (FONTOBJ *)ptr, count, buffer );
427 break;
428 case PALETTE_MAGIC:
429 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
430 break;
432 GDI_HEAP_UNLOCK( handle );
433 return result;
437 /***********************************************************************
438 * GetObject32A (GDI32.204)
440 INT32 WINAPI GetObject32A( HANDLE32 handle, INT32 count, LPVOID buffer )
442 GDIOBJHDR * ptr = NULL;
443 INT32 result = 0;
444 TRACE(gdi, "%08x %d %p\n", handle, count, buffer );
445 if (!count) return 0;
447 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
448 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
449 else
450 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
451 if (!ptr) return 0;
453 switch(ptr->wMagic)
455 case PEN_MAGIC:
456 result = PEN_GetObject32( (PENOBJ *)ptr, count, buffer );
457 break;
458 case BRUSH_MAGIC:
459 result = BRUSH_GetObject32( (BRUSHOBJ *)ptr, count, buffer );
460 break;
461 case BITMAP_MAGIC:
462 result = BITMAP_GetObject32( (BITMAPOBJ *)ptr, count, buffer );
463 break;
464 case FONT_MAGIC:
465 result = FONT_GetObject32A( (FONTOBJ *)ptr, count, buffer );
466 break;
467 case PALETTE_MAGIC:
468 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
469 break;
470 default:
471 FIXME(gdi, "Magic %04x not implemented\n",
472 ptr->wMagic );
473 break;
475 GDI_HEAP_UNLOCK( handle );
476 return result;
478 /***********************************************************************
479 * GetObject32W (GDI32.206)
481 INT32 WINAPI GetObject32W( HANDLE32 handle, INT32 count, LPVOID buffer )
483 GDIOBJHDR * ptr = NULL;
484 INT32 result = 0;
485 TRACE(gdi, "%08x %d %p\n", handle, count, buffer );
486 if (!count) return 0;
488 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
489 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
490 else
491 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
492 if (!ptr) return 0;
494 switch(ptr->wMagic)
496 case PEN_MAGIC:
497 result = PEN_GetObject32( (PENOBJ *)ptr, count, buffer );
498 break;
499 case BRUSH_MAGIC:
500 result = BRUSH_GetObject32( (BRUSHOBJ *)ptr, count, buffer );
501 break;
502 case BITMAP_MAGIC:
503 result = BITMAP_GetObject32( (BITMAPOBJ *)ptr, count, buffer );
504 break;
505 case FONT_MAGIC:
506 result = FONT_GetObject32W( (FONTOBJ *)ptr, count, buffer );
507 break;
508 case PALETTE_MAGIC:
509 result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
510 break;
511 default:
512 FIXME(gdi, "Magic %04x not implemented\n",
513 ptr->wMagic );
514 break;
516 GDI_HEAP_UNLOCK( handle );
517 return result;
520 /***********************************************************************
521 * GetObjectType (GDI32.205)
523 DWORD WINAPI GetObjectType( HANDLE32 handle )
525 GDIOBJHDR * ptr = NULL;
526 INT32 result = 0;
527 TRACE(gdi, "%08x\n", handle );
529 if ((handle >= FIRST_STOCK_HANDLE) && (handle <= LAST_STOCK_HANDLE))
530 ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
531 else
532 ptr = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
533 if (!ptr) return 0;
535 switch(ptr->wMagic)
537 case PEN_MAGIC:
538 result = OBJ_PEN;
539 break;
540 case BRUSH_MAGIC:
541 result = OBJ_BRUSH;
542 break;
543 case BITMAP_MAGIC:
544 result = OBJ_BITMAP;
545 break;
546 case FONT_MAGIC:
547 result = OBJ_FONT;
548 break;
549 case PALETTE_MAGIC:
550 result = OBJ_PAL;
551 break;
552 case REGION_MAGIC:
553 result = OBJ_REGION;
554 break;
555 case DC_MAGIC:
556 result = OBJ_DC;
557 break;
558 case META_DC_MAGIC:
559 result = OBJ_METADC;
560 break;
561 case METAFILE_MAGIC:
562 result = OBJ_METAFILE;
563 break;
564 case METAFILE_DC_MAGIC:
565 result = OBJ_METADC;
566 break;
568 default:
569 FIXME(gdi, "Magic %04x not implemented\n",
570 ptr->wMagic );
571 break;
573 GDI_HEAP_UNLOCK( handle );
574 return result;
577 /***********************************************************************
578 * GetCurrentObject (GDI32.166)
580 HANDLE32 WINAPI GetCurrentObject(HDC32 hdc,UINT32 type)
582 DC * dc = DC_GetDCPtr( hdc );
584 if (!dc)
585 return 0;
586 switch (type) {
587 case OBJ_PEN: return dc->w.hPen;
588 case OBJ_BRUSH: return dc->w.hBrush;
589 case OBJ_PAL: return dc->w.hPalette;
590 case OBJ_FONT: return dc->w.hFont;
591 case OBJ_BITMAP: return dc->w.hBitmap;
592 default:
593 /* the SDK only mentions those above */
594 WARN(gdi,"(%08x,%d): unknown type.\n",hdc,type);
595 return 0;
600 /***********************************************************************
601 * SelectObject16 (GDI.45)
603 HGDIOBJ16 WINAPI SelectObject16( HDC16 hdc, HGDIOBJ16 handle )
605 return (HGDIOBJ16)SelectObject32( hdc, handle );
609 /***********************************************************************
610 * SelectObject32 (GDI32.299)
612 HGDIOBJ32 WINAPI SelectObject32( HDC32 hdc, HGDIOBJ32 handle )
614 DC * dc = DC_GetDCPtr( hdc );
615 if (!dc || !dc->funcs->pSelectObject) return 0;
616 TRACE(gdi, "hdc=%04x %04x\n", hdc, handle );
617 return dc->funcs->pSelectObject( dc, handle );
621 /***********************************************************************
622 * UnrealizeObject16 (GDI.150)
624 BOOL16 WINAPI UnrealizeObject16( HGDIOBJ16 obj )
626 return UnrealizeObject32( obj );
630 /***********************************************************************
631 * UnrealizeObject (GDI32.358)
633 BOOL32 WINAPI UnrealizeObject32( HGDIOBJ32 obj )
635 BOOL32 result = TRUE;
636 /* Check if object is valid */
638 GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_LOCK( obj );
639 if (!header) return FALSE;
641 TRACE(gdi, "%04x\n", obj );
643 /* Unrealize object */
645 switch(header->wMagic)
647 case PALETTE_MAGIC:
648 result = PALETTE_UnrealizeObject( obj, (PALETTEOBJ *)header );
649 break;
651 case BRUSH_MAGIC:
652 /* Windows resets the brush origin. We don't need to. */
653 break;
655 GDI_HEAP_UNLOCK( obj );
656 return result;
660 /***********************************************************************
661 * EnumObjects16 (GDI.71)
663 INT16 WINAPI EnumObjects16( HDC16 hdc, INT16 nObjType,
664 GOBJENUMPROC16 lpEnumFunc, LPARAM lParam )
666 /* Solid colors to enumerate */
667 static const COLORREF solid_colors[] =
668 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
669 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
670 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
671 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
672 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
673 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
674 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
675 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
678 INT16 i, retval = 0;
679 LOGPEN16 *pen;
680 LOGBRUSH16 *brush = NULL;
682 TRACE(gdi, "%04x %d %08lx %08lx\n",
683 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
684 switch(nObjType)
686 case OBJ_PEN:
687 /* Enumerate solid pens */
688 if (!(pen = SEGPTR_NEW(LOGPEN16))) break;
689 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
691 pen->lopnStyle = PS_SOLID;
692 pen->lopnWidth.x = 1;
693 pen->lopnWidth.y = 0;
694 pen->lopnColor = solid_colors[i];
695 retval = lpEnumFunc( SEGPTR_GET(pen), lParam );
696 TRACE(gdi, "solid pen %08lx, ret=%d\n",
697 solid_colors[i], retval);
698 if (!retval) break;
700 SEGPTR_FREE(pen);
701 break;
703 case OBJ_BRUSH:
704 /* Enumerate solid brushes */
705 if (!(brush = SEGPTR_NEW(LOGBRUSH16))) break;
706 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
708 brush->lbStyle = BS_SOLID;
709 brush->lbColor = solid_colors[i];
710 brush->lbHatch = 0;
711 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
712 TRACE(gdi, "solid brush %08lx, ret=%d\n",
713 solid_colors[i], retval);
714 if (!retval) break;
717 /* Now enumerate hatched brushes */
718 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
720 brush->lbStyle = BS_HATCHED;
721 brush->lbColor = RGB(0,0,0);
722 brush->lbHatch = i;
723 retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
724 TRACE(gdi, "hatched brush %d, ret=%d\n",
725 i, retval);
726 if (!retval) break;
728 SEGPTR_FREE(brush);
729 break;
731 default:
732 WARN(gdi, "(%d): Invalid type\n", nObjType );
733 break;
735 return retval;
739 /***********************************************************************
740 * EnumObjects32 (GDI32.89)
742 INT32 WINAPI EnumObjects32( HDC32 hdc, INT32 nObjType,
743 GOBJENUMPROC32 lpEnumFunc, LPARAM lParam )
745 /* Solid colors to enumerate */
746 static const COLORREF solid_colors[] =
747 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
748 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
749 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
750 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
751 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
752 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
753 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
754 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
757 INT32 i, retval = 0;
758 LOGPEN32 pen;
759 LOGBRUSH32 brush;
761 TRACE(gdi, "%04x %d %08lx %08lx\n",
762 hdc, nObjType, (DWORD)lpEnumFunc, lParam );
763 switch(nObjType)
765 case OBJ_PEN:
766 /* Enumerate solid pens */
767 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
769 pen.lopnStyle = PS_SOLID;
770 pen.lopnWidth.x = 1;
771 pen.lopnWidth.y = 0;
772 pen.lopnColor = solid_colors[i];
773 retval = lpEnumFunc( &pen, lParam );
774 TRACE(gdi, "solid pen %08lx, ret=%d\n",
775 solid_colors[i], retval);
776 if (!retval) break;
778 break;
780 case OBJ_BRUSH:
781 /* Enumerate solid brushes */
782 for (i = 0; i < sizeof(solid_colors)/sizeof(solid_colors[0]); i++)
784 brush.lbStyle = BS_SOLID;
785 brush.lbColor = solid_colors[i];
786 brush.lbHatch = 0;
787 retval = lpEnumFunc( &brush, lParam );
788 TRACE(gdi, "solid brush %08lx, ret=%d\n",
789 solid_colors[i], retval);
790 if (!retval) break;
793 /* Now enumerate hatched brushes */
794 if (retval) for (i = HS_HORIZONTAL; i <= HS_DIAGCROSS; i++)
796 brush.lbStyle = BS_HATCHED;
797 brush.lbColor = RGB(0,0,0);
798 brush.lbHatch = i;
799 retval = lpEnumFunc( &brush, lParam );
800 TRACE(gdi, "hatched brush %d, ret=%d\n",
801 i, retval);
802 if (!retval) break;
804 break;
806 default:
807 /* FIXME: implement Win32 types */
808 WARN( gdi, "(%d): Invalid type\n", nObjType );
809 break;
811 return retval;
815 /***********************************************************************
816 * IsGDIObject (GDI.462)
818 * returns type of object if valid (W95 system programming secrets p. 264-5)
820 BOOL16 WINAPI IsGDIObject( HGDIOBJ16 handle )
822 UINT16 magic = 0;
824 if (handle >= FIRST_STOCK_HANDLE )
826 switch (handle)
828 case STOCK_WHITE_BRUSH:
829 case STOCK_LTGRAY_BRUSH:
830 case STOCK_GRAY_BRUSH:
831 case STOCK_DKGRAY_BRUSH:
832 case STOCK_BLACK_BRUSH:
833 case STOCK_HOLLOW_BRUSH:
834 magic = BRUSH_MAGIC;
835 break;
837 case STOCK_WHITE_PEN:
838 case STOCK_BLACK_PEN:
839 case STOCK_NULL_PEN :
840 magic = PEN_MAGIC;
841 break;
843 case STOCK_OEM_FIXED_FONT:
844 case STOCK_ANSI_FIXED_FONT:
845 case STOCK_ANSI_VAR_FONT:
846 case STOCK_SYSTEM_FONT:
847 case STOCK_DEVICE_DEFAULT_FONT:
848 case STOCK_SYSTEM_FIXED_FONT:
849 case STOCK_DEFAULT_GUI_FONT:
850 magic = FONT_MAGIC;
851 break;
853 case STOCK_DEFAULT_PALETTE:
854 magic = PALETTE_MAGIC;
855 break;
858 else
860 GDIOBJHDR *object = (GDIOBJHDR *) GDI_HEAP_LOCK( handle );
861 if (object)
863 magic = object->wMagic;
864 GDI_HEAP_UNLOCK( handle );
868 if (magic >= PEN_MAGIC && magic <= METAFILE_DC_MAGIC)
869 return magic - PEN_MAGIC + 1;
870 else
871 return FALSE;
875 /***********************************************************************
876 * SetObjectOwner16 (GDI.461)
878 void WINAPI SetObjectOwner16( HGDIOBJ16 handle, HANDLE16 owner )
880 /* Nothing to do */
884 /***********************************************************************
885 * SetObjectOwner32 (GDI32.386)
887 void WINAPI SetObjectOwner32( HGDIOBJ32 handle, HANDLE32 owner )
889 /* Nothing to do */
892 /***********************************************************************
893 * MakeObjectPrivate (GDI.463)
895 void WINAPI MakeObjectPrivate( HGDIOBJ16 handle, BOOL16 private )
897 /* FIXME */
901 /***********************************************************************
902 * GdiFlush (GDI32.128)
904 BOOL32 WINAPI GdiFlush(void)
906 return TRUE; /* FIXME */
910 /***********************************************************************
911 * GdiGetBatchLimit (GDI32.129)
913 DWORD WINAPI GdiGetBatchLimit(void)
915 return 1; /* FIXME */
919 /***********************************************************************
920 * GdiSetBatchLimit (GDI32.139)
922 DWORD WINAPI GdiSetBatchLimit( DWORD limit )
924 return 1; /* FIXME */
928 /***********************************************************************
929 * GdiSeeGdiDo (GDI.452)
931 DWORD WINAPI GdiSeeGdiDo( WORD wReqType, WORD wParam1, WORD wParam2,
932 WORD wParam3 )
934 switch (wReqType)
936 case 0x0001: /* LocalAlloc */
937 return LOCAL_Alloc( GDI_HeapSel, wParam1, wParam3 );
938 case 0x0002: /* LocalFree */
939 return LOCAL_Free( GDI_HeapSel, wParam1 );
940 case 0x0003: /* LocalCompact */
941 return LOCAL_Compact( GDI_HeapSel, wParam3, 0 );
942 case 0x0103: /* LocalHeap */
943 return GDI_HeapSel;
944 default:
945 WARN(gdi, "(wReqType=%04x): Unknown\n", wReqType);
946 return (DWORD)-1;
950 /***********************************************************************
951 * GdiFreeResources (GDI.609)
953 WORD WINAPI GdiFreeResources( DWORD reserve )
955 return (WORD)( (int)LOCAL_CountFree( GDI_HeapSel ) * 100 /
956 (int)LOCAL_HeapSize( GDI_HeapSel ) );
959 /***********************************************************************
960 * MulDiv16 (GDI.128)
962 INT16 WINAPI MulDiv16( INT16 foo, INT16 bar, INT16 baz )
964 INT32 ret;
965 if (!baz) return -32768;
966 ret = (foo * bar) / baz;
967 if ((ret > 32767) || (ret < -32767)) return -32768;
968 return ret;
972 /***********************************************************************
973 * MulDiv32 (KERNEL32.391)
974 * RETURNS
975 * Result of multiplication and division
976 * -1: Overflow occurred or Divisor was 0
978 INT32 WINAPI MulDiv32(
979 INT32 nMultiplicand,
980 INT32 nMultiplier,
981 INT32 nDivisor
983 #if (SIZEOF_LONG_LONG >= 8)
984 long long ret;
985 if (!nDivisor) return -1;
986 ret = ((long long)nMultiplicand * nMultiplier) / nDivisor;
987 if ((ret > 2147483647) || (ret < -2147483647)) return -1;
988 return ret;
989 #else
990 if (!nDivisor) return -1;
991 return (nMultiplicand * nMultiplier) / nDivisor;
992 #endif
994 /*******************************************************************
995 * GetColorAdjustment [GDI32.164]
999 BOOL32 WINAPI GetColorAdjustment32(HDC32 hdc, LPCOLORADJUSTMENT lpca)
1001 FIXME(gdi, "GetColorAdjustment, stub\n");
1002 return 0;
1005 /*******************************************************************
1006 * GetMiterLimit [GDI32.201]
1010 BOOL32 WINAPI GetMiterLimit(HDC32 hdc, PFLOAT peLimit)
1012 FIXME(gdi, "GetMiterLimit, stub\n");
1013 return 0;
1016 /*******************************************************************
1017 * SetMiterLimit [GDI32.325]
1021 BOOL32 WINAPI SetMiterLimit(HDC32 hdc, FLOAT eNewLimit, PFLOAT peOldLimit)
1023 FIXME(gdi, "SetMiterLimit, stub\n");
1024 return 0;
1027 /*******************************************************************
1028 * GdiComment [GDI32.109]
1032 BOOL32 WINAPI GdiComment32(HDC32 hdc, UINT32 cbSize, const BYTE *lpData)
1034 FIXME(gdi, "GdiComment, stub\n");
1035 return 0;
1037 /*******************************************************************
1038 * SetColorAdjustment [GDI32.309]
1042 BOOL32 WINAPI SetColorAdjustment32(HDC32 hdc, const COLORADJUSTMENT* lpca)
1044 FIXME(gdi, "SetColorAdjustment, stub\n");
1045 return 0;