4 * Copyright 1993 Alexandre Julliard
21 #include "debugtools.h"
28 DEFAULT_DEBUG_CHANNEL(gdi
)
30 /**********************************************************************/
32 GDI_DRIVER
*GDI_Driver
= NULL
;
34 /***********************************************************************
38 static BRUSHOBJ WhiteBrush
=
40 { 0, BRUSH_MAGIC
, 1 }, /* header */
41 { BS_SOLID
, RGB(255,255,255), 0 } /* logbrush */
44 static BRUSHOBJ LtGrayBrush
=
46 { 0, BRUSH_MAGIC
, 1 }, /* header */
47 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
48 { BS_SOLID
, RGB(192,192,192), 0 } /* logbrush */
51 static BRUSHOBJ GrayBrush
=
53 { 0, BRUSH_MAGIC
, 1 }, /* header */
54 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
55 { BS_SOLID
, RGB(128,128,128), 0 } /* logbrush */
58 static BRUSHOBJ DkGrayBrush
=
60 { 0, BRUSH_MAGIC
, 1 }, /* header */
61 /* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
62 /* NB_HATCH_STYLES is an index into HatchBrushes */
63 { BS_HATCHED
, RGB(0,0,0), NB_HATCH_STYLES
} /* logbrush */
66 static BRUSHOBJ BlackBrush
=
68 { 0, BRUSH_MAGIC
, 1 }, /* header */
69 { BS_SOLID
, RGB(0,0,0), 0 } /* logbrush */
72 static BRUSHOBJ NullBrush
=
74 { 0, BRUSH_MAGIC
, 1 }, /* header */
75 { BS_NULL
, 0, 0 } /* logbrush */
78 static PENOBJ WhitePen
=
80 { 0, PEN_MAGIC
, 1 }, /* header */
81 { PS_SOLID
, { 1, 0 }, RGB(255,255,255) } /* logpen */
84 static PENOBJ BlackPen
=
86 { 0, PEN_MAGIC
, 1 }, /* header */
87 { PS_SOLID
, { 1, 0 }, RGB(0,0,0) } /* logpen */
90 static PENOBJ NullPen
=
92 { 0, PEN_MAGIC
, 1 }, /* header */
93 { PS_NULL
, { 1, 0 }, 0 } /* logpen */
96 static FONTOBJ OEMFixedFont
=
98 { 0, FONT_MAGIC
, 1 }, /* header */
99 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, OEM_CHARSET
,
100 0, 0, DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, "" }
102 /* Filler to make the location counter dword aligned again. This is necessary
103 since (a) FONTOBJ is packed, (b) gcc places initialised variables in the code
104 segment, and (c) Solaris assembler is stupid. */
105 static UINT16 align_OEMFixedFont
= 1;
107 static FONTOBJ AnsiFixedFont
=
109 { 0, FONT_MAGIC
, 1 }, /* header */
110 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
111 0, 0, DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, "" }
113 static UINT16 align_AnsiFixedFont
= 1;
115 static FONTOBJ AnsiVarFont
=
117 { 0, FONT_MAGIC
, 1 }, /* header */
118 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
119 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "MS Sans Serif" }
121 static UINT16 align_AnsiVarFont
= 1;
123 static FONTOBJ SystemFont
=
125 { 0, FONT_MAGIC
, 1 },
126 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
127 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "System" }
129 static UINT16 align_SystemFont
= 1;
131 static FONTOBJ DeviceDefaultFont
=
133 { 0, FONT_MAGIC
, 1 }, /* header */
134 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
135 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "" }
137 static UINT16 align_DeviceDefaultFont
= 1;
139 static FONTOBJ SystemFixedFont
=
141 { 0, FONT_MAGIC
, 1 }, /* header */
142 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
143 0, 0, DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, "" }
145 static UINT16 align_SystemFixedFont
= 1;
147 /* FIXME: Is this correct? */
148 static FONTOBJ DefaultGuiFont
=
150 { 0, FONT_MAGIC
, 1 }, /* header */
151 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
152 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "MS Sans Serif" }
154 static UINT16 align_DefaultGuiFont
= 1;
157 static GDIOBJHDR
* StockObjects
[NB_STOCK_OBJECTS
] =
159 (GDIOBJHDR
*) &WhiteBrush
,
160 (GDIOBJHDR
*) &LtGrayBrush
,
161 (GDIOBJHDR
*) &GrayBrush
,
162 (GDIOBJHDR
*) &DkGrayBrush
,
163 (GDIOBJHDR
*) &BlackBrush
,
164 (GDIOBJHDR
*) &NullBrush
,
165 (GDIOBJHDR
*) &WhitePen
,
166 (GDIOBJHDR
*) &BlackPen
,
167 (GDIOBJHDR
*) &NullPen
,
169 (GDIOBJHDR
*) &OEMFixedFont
,
170 (GDIOBJHDR
*) &AnsiFixedFont
,
171 (GDIOBJHDR
*) &AnsiVarFont
,
172 (GDIOBJHDR
*) &SystemFont
,
173 (GDIOBJHDR
*) &DeviceDefaultFont
,
174 NULL
, /* DEFAULT_PALETTE created by PALETTE_Init */
175 (GDIOBJHDR
*) &SystemFixedFont
,
176 (GDIOBJHDR
*) &DefaultGuiFont
179 HBITMAP hPseudoStockBitmap
; /* 1x1 bitmap for memory DCs */
181 /******************************************************************************
183 * void ReadFontInformation(
184 * char const *fontName,
192 * ReadFontInformation() checks the Wine configuration file's Tweak.Fonts
193 * section for entries containing fontName.Height, fontName.Bold, etc.,
194 * where fontName is the name specified in the call (e.g., "System"). It
195 * attempts to be user friendly by accepting 'n', 'N', 'f', 'F', or '0' as
196 * the first character in the boolean attributes (bold, italic, and
198 *****************************************************************************/
200 static void ReadFontInformation(
201 char const *fontName
,
211 /* In order for the stock fonts to be independent of
212 * mapping mode, the height (& width) must be 0
214 sprintf(key
, "%s.Height", fontName
);
215 font
->logfont
.lfHeight
=
216 PROFILE_GetWineIniInt("Tweak.Fonts", key
, defHeight
);
218 sprintf(key
, "%s.Bold", fontName
);
219 font
->logfont
.lfWeight
=
220 (PROFILE_GetWineIniBool("Tweak.Fonts", key
, defBold
)) ?
223 sprintf(key
, "%s.Italic", fontName
);
224 font
->logfont
.lfItalic
=
225 PROFILE_GetWineIniBool("Tweak.Fonts", key
, defItalic
);
227 sprintf(key
, "%s.Underline", fontName
);
228 font
->logfont
.lfUnderline
=
229 PROFILE_GetWineIniBool("Tweak.Fonts", key
, defUnderline
);
231 sprintf(key
, "%s.StrikeOut", fontName
);
232 font
->logfont
.lfStrikeOut
=
233 PROFILE_GetWineIniBool("Tweak.Fonts", key
, defStrikeOut
);
238 /***********************************************************************
239 * Because the stock fonts have their structure initialized with
240 * a height of 0 to keep them independent of mapping mode, simply
241 * returning the LOGFONT as is will not work correctly.
242 * These "FixStockFontSizeXXX()" methods will get the correct
243 * size for the fonts.
245 static void GetFontMetrics(HFONT handle
, LPTEXTMETRICA lptm
)
250 hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
252 hOldFont
= (HFONT
)SelectObject(hdc
, handle
);
254 GetTextMetricsA(hdc
, lptm
);
256 SelectObject(hdc
, hOldFont
);
261 static inline void FixStockFontSize16(
267 LOGFONT16
* pLogFont
= (LOGFONT16
*)buffer
;
270 * Was the lfHeight field copied (it's the first field)?
271 * If it was and it was null, replace the height.
273 if ( (count
>= 2*sizeof(INT16
)) &&
274 (pLogFont
->lfHeight
== 0) )
276 GetFontMetrics(handle
, &tm
);
278 pLogFont
->lfHeight
= tm
.tmHeight
;
279 pLogFont
->lfWidth
= tm
.tmAveCharWidth
;
283 static inline void FixStockFontSizeA(
289 LOGFONTA
* pLogFont
= (LOGFONTA
*)buffer
;
292 * Was the lfHeight field copied (it's the first field)?
293 * If it was and it was null, replace the height.
295 if ( (count
>= 2*sizeof(INT
)) &&
296 (pLogFont
->lfHeight
== 0) )
298 GetFontMetrics(handle
, &tm
);
300 pLogFont
->lfHeight
= tm
.tmHeight
;
301 pLogFont
->lfWidth
= tm
.tmAveCharWidth
;
306 * Since the LOGFONTA and LOGFONTW structures are identical up to the
307 * lfHeight member (the one of interest in this case) we simply define
308 * the W version as the A version.
310 #define FixStockFontSizeW FixStockFontSizeA
314 /***********************************************************************
317 * GDI initialization.
321 BOOL systemIsBold
= (TWEAK_WineLook
== WIN31_LOOK
);
323 /* Kill some warnings. */
324 (void)align_OEMFixedFont
;
325 (void)align_AnsiFixedFont
;
326 (void)align_AnsiVarFont
;
327 (void)align_SystemFont
;
328 (void)align_DeviceDefaultFont
;
329 (void)align_SystemFixedFont
;
330 (void)align_DefaultGuiFont
;
332 /* TWEAK: Initialize font hints */
333 ReadFontInformation("OEMFixed", &OEMFixedFont
, 0, 0, 0, 0, 0);
334 ReadFontInformation("AnsiFixed", &AnsiFixedFont
, 0, 0, 0, 0, 0);
335 ReadFontInformation("AnsiVar", &AnsiVarFont
, 0, 0, 0, 0, 0);
336 ReadFontInformation("System", &SystemFont
, 0, systemIsBold
, 0, 0, 0);
337 ReadFontInformation("DeviceDefault", &DeviceDefaultFont
, 0, 0, 0, 0, 0);
338 ReadFontInformation("SystemFixed", &SystemFixedFont
, 0, systemIsBold
, 0, 0, 0);
339 ReadFontInformation("DefaultGui", &DefaultGuiFont
, 0, 0, 0, 0, 0);
341 /* Initialize drivers */
343 GDI_Driver
->pInitialize();
345 /* Create default palette */
347 /* DR well *this* palette can't be moveable (?) */
349 HPALETTE16 hpalette
= PALETTE_Init();
352 StockObjects
[DEFAULT_PALETTE
] = (GDIOBJHDR
*)GDI_HEAP_LOCK( hpalette
);
355 hPseudoStockBitmap
= CreateBitmap( 1, 1, 1, 1, NULL
);
360 /***********************************************************************
363 HGDIOBJ
GDI_AllocObject( WORD size
, WORD magic
)
365 static DWORD count
= 0;
368 if ( magic
== DC_MAGIC
|| magic
== METAFILE_DC_MAGIC
)
369 handle
= GDI_HEAP_ALLOC( size
);
371 handle
= GDI_HEAP_ALLOC_MOVEABLE( size
);
372 if (!handle
) return 0;
373 obj
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
376 obj
->dwCount
= ++count
;
377 GDI_HEAP_UNLOCK( handle
);
382 /***********************************************************************
385 BOOL
GDI_FreeObject( HGDIOBJ handle
)
389 /* Can't free stock objects */
390 if ((handle
>= FIRST_STOCK_HANDLE
) && (handle
<= LAST_STOCK_HANDLE
))
393 object
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
394 if (!object
) return FALSE
;
395 object
->wMagic
= 0; /* Mark it as invalid */
399 GDI_HEAP_FREE( handle
);
403 /***********************************************************************
406 * Return a pointer to the GDI object associated to the handle.
407 * Return NULL if the object has the wrong magic number.
408 * Movable GDI objects are locked in memory: it is up to the caller to unlock
409 * it after the caller is done with the pointer.
411 GDIOBJHDR
* GDI_GetObjPtr( HGDIOBJ handle
, WORD magic
)
413 GDIOBJHDR
* ptr
= NULL
;
415 if (handle
>= FIRST_STOCK_HANDLE
)
417 if (handle
<= LAST_STOCK_HANDLE
) ptr
= StockObjects
[handle
- FIRST_STOCK_HANDLE
];
420 ptr
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
421 if (!ptr
) return NULL
;
422 if ((magic
!= MAGIC_DONTCARE
) && (ptr
->wMagic
!= magic
))
424 GDI_HEAP_UNLOCK( handle
);
431 /***********************************************************************
432 * DeleteObject16 (GDI.69)
434 BOOL16 WINAPI
DeleteObject16( HGDIOBJ16 obj
)
436 return DeleteObject( obj
);
440 /***********************************************************************
441 * DeleteObject32 (GDI32.70)
443 BOOL WINAPI
DeleteObject( HGDIOBJ obj
)
445 /* Check if object is valid */
448 if (HIWORD(obj
)) return FALSE
;
449 if ((obj
>= FIRST_STOCK_HANDLE
) && (obj
<= LAST_STOCK_HANDLE
))
451 if (obj
== hPseudoStockBitmap
) return TRUE
;
452 if (!(header
= (GDIOBJHDR
*) GDI_HEAP_LOCK( obj
))) return FALSE
;
454 TRACE("%04x\n", obj
);
458 switch(header
->wMagic
)
460 case PEN_MAGIC
: return GDI_FreeObject( obj
);
461 case BRUSH_MAGIC
: return BRUSH_DeleteObject( obj
, (BRUSHOBJ
*)header
);
462 case FONT_MAGIC
: return GDI_FreeObject( obj
);
463 case PALETTE_MAGIC
: return PALETTE_DeleteObject(obj
,(PALETTEOBJ
*)header
);
464 case BITMAP_MAGIC
: return BITMAP_DeleteObject( obj
, (BITMAPOBJ
*)header
);
465 case REGION_MAGIC
: return REGION_DeleteObject( obj
, (RGNOBJ
*)header
);
466 case DC_MAGIC
: return DeleteDC(obj
);
468 WARN("Already deleted\n");
471 WARN("Unknown magic number (%d)\n",header
->wMagic
);
476 /***********************************************************************
477 * GetStockObject16 (GDI.87)
479 HGDIOBJ16 WINAPI
GetStockObject16( INT16 obj
)
481 return (HGDIOBJ16
)GetStockObject( obj
);
485 /***********************************************************************
486 * GetStockObject32 (GDI32.220)
488 HGDIOBJ WINAPI
GetStockObject( INT obj
)
490 if ((obj
< 0) || (obj
>= NB_STOCK_OBJECTS
)) return 0;
491 if (!StockObjects
[obj
]) return 0;
492 TRACE("returning %d\n",
493 FIRST_STOCK_HANDLE
+ obj
);
494 return (HGDIOBJ16
)(FIRST_STOCK_HANDLE
+ obj
);
498 /***********************************************************************
499 * GetObject16 (GDI.82)
501 INT16 WINAPI
GetObject16( HANDLE16 handle
, INT16 count
, LPVOID buffer
)
505 TRACE("%04x %d %p\n", handle
, count
, buffer
);
506 if (!count
) return 0;
508 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
513 result
= PEN_GetObject16( (PENOBJ
*)ptr
, count
, buffer
);
516 result
= BRUSH_GetObject16( (BRUSHOBJ
*)ptr
, count
, buffer
);
519 result
= BITMAP_GetObject16( (BITMAPOBJ
*)ptr
, count
, buffer
);
522 result
= FONT_GetObject16( (FONTOBJ
*)ptr
, count
, buffer
);
525 * Fix the LOGFONT structure for the stock fonts
527 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
528 (handle
<= LAST_STOCK_HANDLE
) )
529 FixStockFontSize16(handle
, count
, buffer
);
532 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
535 GDI_HEAP_UNLOCK( handle
);
540 /***********************************************************************
541 * GetObject32A (GDI32.204)
543 INT WINAPI
GetObjectA( HANDLE handle
, INT count
, LPVOID buffer
)
547 TRACE("%08x %d %p\n", handle
, count
, buffer
);
548 if (!count
) return 0;
550 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
555 result
= PEN_GetObject( (PENOBJ
*)ptr
, count
, buffer
);
558 result
= BRUSH_GetObject( (BRUSHOBJ
*)ptr
, count
, buffer
);
561 result
= BITMAP_GetObject( (BITMAPOBJ
*)ptr
, count
, buffer
);
564 result
= FONT_GetObjectA( (FONTOBJ
*)ptr
, count
, buffer
);
567 * Fix the LOGFONT structure for the stock fonts
569 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
570 (handle
<= LAST_STOCK_HANDLE
) )
571 FixStockFontSizeA(handle
, count
, buffer
);
574 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
579 case DISABLED_DC_MAGIC
:
582 case METAFILE_DC_MAGIC
:
583 case ENHMETAFILE_MAGIC
:
584 case ENHMETAFILE_DC_MAGIC
:
585 FIXME("Magic %04x not implemented\n",
590 ERR("Invalid GDI Magic %04x\n", ptr
->wMagic
);
593 GDI_HEAP_UNLOCK( handle
);
597 /***********************************************************************
598 * GetObject32W (GDI32.206)
600 INT WINAPI
GetObjectW( HANDLE handle
, INT count
, LPVOID buffer
)
604 TRACE("%08x %d %p\n", handle
, count
, buffer
);
605 if (!count
) return 0;
607 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
612 result
= PEN_GetObject( (PENOBJ
*)ptr
, count
, buffer
);
615 result
= BRUSH_GetObject( (BRUSHOBJ
*)ptr
, count
, buffer
);
618 result
= BITMAP_GetObject( (BITMAPOBJ
*)ptr
, count
, buffer
);
621 result
= FONT_GetObjectW( (FONTOBJ
*)ptr
, count
, buffer
);
624 * Fix the LOGFONT structure for the stock fonts
626 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
627 (handle
<= LAST_STOCK_HANDLE
) )
628 FixStockFontSizeW(handle
, count
, buffer
);
631 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
634 FIXME("Magic %04x not implemented\n",
638 GDI_HEAP_UNLOCK( handle
);
642 /***********************************************************************
643 * GetObjectType (GDI32.205)
645 DWORD WINAPI
GetObjectType( HANDLE handle
)
649 TRACE("%08x\n", handle
);
651 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
680 result
= OBJ_METAFILE
;
682 case METAFILE_DC_MAGIC
:
685 case ENHMETAFILE_MAGIC
:
686 result
= OBJ_ENHMETAFILE
;
688 case ENHMETAFILE_DC_MAGIC
:
689 result
= OBJ_ENHMETADC
;
692 FIXME("Magic %04x not implemented\n",
696 GDI_HEAP_UNLOCK( handle
);
700 /***********************************************************************
701 * GetCurrentObject (GDI32.166)
703 HANDLE WINAPI
GetCurrentObject(HDC hdc
,UINT type
)
705 DC
* dc
= DC_GetDCPtr( hdc
);
710 case OBJ_PEN
: return dc
->w
.hPen
;
711 case OBJ_BRUSH
: return dc
->w
.hBrush
;
712 case OBJ_PAL
: return dc
->w
.hPalette
;
713 case OBJ_FONT
: return dc
->w
.hFont
;
714 case OBJ_BITMAP
: return dc
->w
.hBitmap
;
716 /* the SDK only mentions those above */
717 WARN("(%08x,%d): unknown type.\n",hdc
,type
);
723 /***********************************************************************
724 * SelectObject16 (GDI.45)
726 HGDIOBJ16 WINAPI
SelectObject16( HDC16 hdc
, HGDIOBJ16 handle
)
728 return (HGDIOBJ16
)SelectObject( hdc
, handle
);
732 /***********************************************************************
733 * SelectObject32 (GDI32.299)
735 HGDIOBJ WINAPI
SelectObject( HDC hdc
, HGDIOBJ handle
)
737 DC
* dc
= DC_GetDCPtr( hdc
);
738 if (!dc
|| !dc
->funcs
->pSelectObject
) return 0;
739 TRACE("hdc=%04x %04x\n", hdc
, handle
);
740 return dc
->funcs
->pSelectObject( dc
, handle
);
744 /***********************************************************************
745 * UnrealizeObject16 (GDI.150)
747 BOOL16 WINAPI
UnrealizeObject16( HGDIOBJ16 obj
)
749 return UnrealizeObject( obj
);
753 /***********************************************************************
754 * UnrealizeObject (GDI32.358)
756 BOOL WINAPI
UnrealizeObject( HGDIOBJ obj
)
759 /* Check if object is valid */
761 GDIOBJHDR
* header
= (GDIOBJHDR
*) GDI_HEAP_LOCK( obj
);
762 if (!header
) return FALSE
;
764 TRACE("%04x\n", obj
);
766 /* Unrealize object */
768 switch(header
->wMagic
)
771 result
= PALETTE_UnrealizeObject( obj
, (PALETTEOBJ
*)header
);
775 /* Windows resets the brush origin. We don't need to. */
778 GDI_HEAP_UNLOCK( obj
);
783 /***********************************************************************
784 * EnumObjects16 (GDI.71)
786 INT16 WINAPI
EnumObjects16( HDC16 hdc
, INT16 nObjType
,
787 GOBJENUMPROC16 lpEnumFunc
, LPARAM lParam
)
789 /* Solid colors to enumerate */
790 static const COLORREF solid_colors
[] =
791 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
792 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
793 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
794 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
795 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
796 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
797 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
798 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
803 LOGBRUSH16
*brush
= NULL
;
805 TRACE("%04x %d %08lx %08lx\n",
806 hdc
, nObjType
, (DWORD
)lpEnumFunc
, lParam
);
810 /* Enumerate solid pens */
811 if (!(pen
= SEGPTR_NEW(LOGPEN16
))) break;
812 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
814 pen
->lopnStyle
= PS_SOLID
;
815 pen
->lopnWidth
.x
= 1;
816 pen
->lopnWidth
.y
= 0;
817 pen
->lopnColor
= solid_colors
[i
];
818 retval
= lpEnumFunc( SEGPTR_GET(pen
), lParam
);
819 TRACE("solid pen %08lx, ret=%d\n",
820 solid_colors
[i
], retval
);
827 /* Enumerate solid brushes */
828 if (!(brush
= SEGPTR_NEW(LOGBRUSH16
))) break;
829 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
831 brush
->lbStyle
= BS_SOLID
;
832 brush
->lbColor
= solid_colors
[i
];
834 retval
= lpEnumFunc( SEGPTR_GET(brush
), lParam
);
835 TRACE("solid brush %08lx, ret=%d\n",
836 solid_colors
[i
], retval
);
840 /* Now enumerate hatched brushes */
841 if (retval
) for (i
= HS_HORIZONTAL
; i
<= HS_DIAGCROSS
; i
++)
843 brush
->lbStyle
= BS_HATCHED
;
844 brush
->lbColor
= RGB(0,0,0);
846 retval
= lpEnumFunc( SEGPTR_GET(brush
), lParam
);
847 TRACE("hatched brush %d, ret=%d\n",
855 WARN("(%d): Invalid type\n", nObjType
);
862 /***********************************************************************
863 * EnumObjects32 (GDI32.89)
865 INT WINAPI
EnumObjects( HDC hdc
, INT nObjType
,
866 GOBJENUMPROC lpEnumFunc
, LPARAM lParam
)
868 /* Solid colors to enumerate */
869 static const COLORREF solid_colors
[] =
870 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
871 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
872 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
873 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
874 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
875 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
876 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
877 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
884 TRACE("%04x %d %08lx %08lx\n",
885 hdc
, nObjType
, (DWORD
)lpEnumFunc
, lParam
);
889 /* Enumerate solid pens */
890 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
892 pen
.lopnStyle
= PS_SOLID
;
895 pen
.lopnColor
= solid_colors
[i
];
896 retval
= lpEnumFunc( &pen
, lParam
);
897 TRACE("solid pen %08lx, ret=%d\n",
898 solid_colors
[i
], retval
);
904 /* Enumerate solid brushes */
905 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
907 brush
.lbStyle
= BS_SOLID
;
908 brush
.lbColor
= solid_colors
[i
];
910 retval
= lpEnumFunc( &brush
, lParam
);
911 TRACE("solid brush %08lx, ret=%d\n",
912 solid_colors
[i
], retval
);
916 /* Now enumerate hatched brushes */
917 if (retval
) for (i
= HS_HORIZONTAL
; i
<= HS_DIAGCROSS
; i
++)
919 brush
.lbStyle
= BS_HATCHED
;
920 brush
.lbColor
= RGB(0,0,0);
922 retval
= lpEnumFunc( &brush
, lParam
);
923 TRACE("hatched brush %d, ret=%d\n",
930 /* FIXME: implement Win32 types */
931 WARN("(%d): Invalid type\n", nObjType
);
938 /***********************************************************************
939 * IsGDIObject (GDI.462)
941 * returns type of object if valid (W95 system programming secrets p. 264-5)
943 BOOL16 WINAPI
IsGDIObject16( HGDIOBJ16 handle
)
947 if (handle
>= FIRST_STOCK_HANDLE
)
951 case STOCK_WHITE_BRUSH
:
952 case STOCK_LTGRAY_BRUSH
:
953 case STOCK_GRAY_BRUSH
:
954 case STOCK_DKGRAY_BRUSH
:
955 case STOCK_BLACK_BRUSH
:
956 case STOCK_HOLLOW_BRUSH
:
960 case STOCK_WHITE_PEN
:
961 case STOCK_BLACK_PEN
:
962 case STOCK_NULL_PEN
:
966 case STOCK_OEM_FIXED_FONT
:
967 case STOCK_ANSI_FIXED_FONT
:
968 case STOCK_ANSI_VAR_FONT
:
969 case STOCK_SYSTEM_FONT
:
970 case STOCK_DEVICE_DEFAULT_FONT
:
971 case STOCK_SYSTEM_FIXED_FONT
:
972 case STOCK_DEFAULT_GUI_FONT
:
976 case STOCK_DEFAULT_PALETTE
:
977 magic
= PALETTE_MAGIC
;
983 GDIOBJHDR
*object
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
986 magic
= object
->wMagic
;
987 GDI_HEAP_UNLOCK( handle
);
991 if (magic
>= PEN_MAGIC
&& magic
<= METAFILE_DC_MAGIC
)
992 return magic
- PEN_MAGIC
+ 1;
998 /***********************************************************************
999 * SetObjectOwner16 (GDI.461)
1001 void WINAPI
SetObjectOwner16( HGDIOBJ16 handle
, HANDLE16 owner
)
1007 /***********************************************************************
1008 * SetObjectOwner32 (GDI32.386)
1010 void WINAPI
SetObjectOwner( HGDIOBJ handle
, HANDLE owner
)
1015 /***********************************************************************
1016 * MakeObjectPrivate (GDI.463)
1018 void WINAPI
MakeObjectPrivate16( HGDIOBJ16 handle
, BOOL16
private )
1024 /***********************************************************************
1025 * GdiFlush (GDI32.128)
1027 BOOL WINAPI
GdiFlush(void)
1029 return TRUE
; /* FIXME */
1033 /***********************************************************************
1034 * GdiGetBatchLimit (GDI32.129)
1036 DWORD WINAPI
GdiGetBatchLimit(void)
1038 return 1; /* FIXME */
1042 /***********************************************************************
1043 * GdiSetBatchLimit (GDI32.139)
1045 DWORD WINAPI
GdiSetBatchLimit( DWORD limit
)
1047 return 1; /* FIXME */
1051 /***********************************************************************
1052 * GdiSeeGdiDo (GDI.452)
1054 DWORD WINAPI
GdiSeeGdiDo16( WORD wReqType
, WORD wParam1
, WORD wParam2
,
1059 case 0x0001: /* LocalAlloc */
1060 return LOCAL_Alloc( GDI_HeapSel
, wParam1
, wParam3
);
1061 case 0x0002: /* LocalFree */
1062 return LOCAL_Free( GDI_HeapSel
, wParam1
);
1063 case 0x0003: /* LocalCompact */
1064 return LOCAL_Compact( GDI_HeapSel
, wParam3
, 0 );
1065 case 0x0103: /* LocalHeap */
1068 WARN("(wReqType=%04x): Unknown\n", wReqType
);
1073 /***********************************************************************
1074 * GdiSignalProc (GDI.610)
1076 WORD WINAPI
GdiSignalProc( UINT uCode
, DWORD dwThreadOrProcessID
,
1077 DWORD dwFlags
, HMODULE16 hModule
)
1082 /***********************************************************************
1083 * FinalGdiInit16 (GDI.405)
1085 void WINAPI
FinalGdiInit16( HANDLE16 unknown
)
1089 /***********************************************************************
1090 * GdiFreeResources (GDI.609)
1092 WORD WINAPI
GdiFreeResources16( DWORD reserve
)
1094 return (WORD
)( (int)LOCAL_CountFree( GDI_HeapSel
) * 100 /
1095 (int)LOCAL_HeapSize( GDI_HeapSel
) );
1098 /***********************************************************************
1099 * MulDiv16 (GDI.128)
1101 INT16 WINAPI
MulDiv16(
1102 INT16 nMultiplicand
,
1107 if (!nDivisor
) return -32768;
1108 /* We want to deal with a positive divisor to simplify the logic. */
1111 nMultiplicand
= - nMultiplicand
;
1112 nDivisor
= -nDivisor
;
1114 /* If the result is positive, we "add" to round. else,
1115 * we subtract to round. */
1116 if ( ( (nMultiplicand
< 0) && (nMultiplier
< 0) ) ||
1117 ( (nMultiplicand
>= 0) && (nMultiplier
>= 0) ) )
1118 ret
= (((int)nMultiplicand
* nMultiplier
) + (nDivisor
/2)) / nDivisor
;
1120 ret
= (((int)nMultiplicand
* nMultiplier
) - (nDivisor
/2)) / nDivisor
;
1121 if ((ret
> 32767) || (ret
< -32767)) return -32768;
1126 /***********************************************************************
1127 * MulDiv32 (KERNEL32.391)
1129 * Result of multiplication and division
1130 * -1: Overflow occurred or Divisor was 0
1137 #if SIZEOF_LONG_LONG >= 8
1140 if (!nDivisor
) return -1;
1142 /* We want to deal with a positive divisor to simplify the logic. */
1145 nMultiplicand
= - nMultiplicand
;
1146 nDivisor
= -nDivisor
;
1149 /* If the result is positive, we "add" to round. else, we subtract to round. */
1150 if ( ( (nMultiplicand
< 0) && (nMultiplier
< 0) ) ||
1151 ( (nMultiplicand
>= 0) && (nMultiplier
>= 0) ) )
1152 ret
= (((long long)nMultiplicand
* nMultiplier
) + (nDivisor
/2)) / nDivisor
;
1154 ret
= (((long long)nMultiplicand
* nMultiplier
) - (nDivisor
/2)) / nDivisor
;
1156 if ((ret
> 2147483647) || (ret
< -2147483647)) return -1;
1159 if (!nDivisor
) return -1;
1161 /* We want to deal with a positive divisor to simplify the logic. */
1164 nMultiplicand
= - nMultiplicand
;
1165 nDivisor
= -nDivisor
;
1168 /* If the result is positive, we "add" to round. else, we subtract to round. */
1169 if ( ( (nMultiplicand
< 0) && (nMultiplier
< 0) ) ||
1170 ( (nMultiplicand
>= 0) && (nMultiplier
>= 0) ) )
1171 return ((nMultiplicand
* nMultiplier
) + (nDivisor
/2)) / nDivisor
;
1173 return ((nMultiplicand
* nMultiplier
) - (nDivisor
/2)) / nDivisor
;
1177 /*******************************************************************
1178 * GetColorAdjustment [GDI32.164]
1182 BOOL WINAPI
GetColorAdjustment(HDC hdc
, LPCOLORADJUSTMENT lpca
)
1184 FIXME("GetColorAdjustment, stub\n");
1188 /*******************************************************************
1189 * GetMiterLimit [GDI32.201]
1193 BOOL WINAPI
GetMiterLimit(HDC hdc
, PFLOAT peLimit
)
1195 FIXME("GetMiterLimit, stub\n");
1199 /*******************************************************************
1200 * SetMiterLimit [GDI32.325]
1204 BOOL WINAPI
SetMiterLimit(HDC hdc
, FLOAT eNewLimit
, PFLOAT peOldLimit
)
1206 FIXME("SetMiterLimit, stub\n");
1210 /*******************************************************************
1211 * GdiComment [GDI32.109]
1215 BOOL WINAPI
GdiComment(HDC hdc
, UINT cbSize
, const BYTE
*lpData
)
1217 FIXME("GdiComment, stub\n");
1220 /*******************************************************************
1221 * SetColorAdjustment [GDI32.309]
1225 BOOL WINAPI
SetColorAdjustment(HDC hdc
, const COLORADJUSTMENT
* lpca
)
1227 FIXME("SetColorAdjustment, stub\n");