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 /* Create default palette */
343 /* DR well *this* palette can't be moveable (?) */
345 HPALETTE16 hpalette
= PALETTE_Init();
348 StockObjects
[DEFAULT_PALETTE
] = (GDIOBJHDR
*)GDI_HEAP_LOCK( hpalette
);
351 hPseudoStockBitmap
= CreateBitmap( 1, 1, 1, 1, NULL
);
356 /***********************************************************************
359 HGDIOBJ
GDI_AllocObject( WORD size
, WORD magic
)
361 static DWORD count
= 0;
364 if ( magic
== DC_MAGIC
|| magic
== METAFILE_DC_MAGIC
)
365 handle
= GDI_HEAP_ALLOC( size
);
367 handle
= GDI_HEAP_ALLOC_MOVEABLE( size
);
368 if (!handle
) return 0;
369 obj
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
372 obj
->dwCount
= ++count
;
373 GDI_HEAP_UNLOCK( handle
);
378 /***********************************************************************
381 BOOL
GDI_FreeObject( HGDIOBJ handle
)
385 /* Can't free stock objects */
386 if ((handle
>= FIRST_STOCK_HANDLE
) && (handle
<= LAST_STOCK_HANDLE
))
389 object
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
390 if (!object
) return FALSE
;
391 object
->wMagic
= 0; /* Mark it as invalid */
395 GDI_HEAP_FREE( handle
);
399 /***********************************************************************
402 * Return a pointer to the GDI object associated to the handle.
403 * Return NULL if the object has the wrong magic number.
404 * Movable GDI objects are locked in memory: it is up to the caller to unlock
405 * it after the caller is done with the pointer.
407 GDIOBJHDR
* GDI_GetObjPtr( HGDIOBJ handle
, WORD magic
)
409 GDIOBJHDR
* ptr
= NULL
;
411 if (handle
>= FIRST_STOCK_HANDLE
)
413 if (handle
<= LAST_STOCK_HANDLE
) ptr
= StockObjects
[handle
- FIRST_STOCK_HANDLE
];
416 ptr
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
417 if (!ptr
) return NULL
;
418 if ((magic
!= MAGIC_DONTCARE
) && (ptr
->wMagic
!= magic
))
420 GDI_HEAP_UNLOCK( handle
);
427 /***********************************************************************
428 * DeleteObject16 (GDI.69)
430 BOOL16 WINAPI
DeleteObject16( HGDIOBJ16 obj
)
432 return DeleteObject( obj
);
436 /***********************************************************************
437 * DeleteObject (GDI32.70)
439 BOOL WINAPI
DeleteObject( HGDIOBJ obj
)
441 /* Check if object is valid */
444 if (HIWORD(obj
)) return FALSE
;
445 if ((obj
>= FIRST_STOCK_HANDLE
) && (obj
<= LAST_STOCK_HANDLE
))
447 if (obj
== hPseudoStockBitmap
) return TRUE
;
448 if (!(header
= (GDIOBJHDR
*) GDI_HEAP_LOCK( obj
))) return FALSE
;
450 TRACE("%04x\n", obj
);
454 switch(header
->wMagic
)
456 case PEN_MAGIC
: return GDI_FreeObject( obj
);
457 case BRUSH_MAGIC
: return BRUSH_DeleteObject( obj
, (BRUSHOBJ
*)header
);
458 case FONT_MAGIC
: return GDI_FreeObject( obj
);
459 case PALETTE_MAGIC
: return PALETTE_DeleteObject(obj
,(PALETTEOBJ
*)header
);
460 case BITMAP_MAGIC
: return BITMAP_DeleteObject( obj
, (BITMAPOBJ
*)header
);
461 case REGION_MAGIC
: return REGION_DeleteObject( obj
, (RGNOBJ
*)header
);
462 case DC_MAGIC
: return DeleteDC(obj
);
464 WARN("Already deleted\n");
467 WARN("Unknown magic number (%d)\n",header
->wMagic
);
472 /***********************************************************************
473 * GetStockObject16 (GDI.87)
475 HGDIOBJ16 WINAPI
GetStockObject16( INT16 obj
)
477 return (HGDIOBJ16
)GetStockObject( obj
);
481 /***********************************************************************
482 * GetStockObject (GDI32.220)
484 HGDIOBJ WINAPI
GetStockObject( INT obj
)
486 if ((obj
< 0) || (obj
>= NB_STOCK_OBJECTS
)) return 0;
487 if (!StockObjects
[obj
]) return 0;
488 TRACE("returning %d\n",
489 FIRST_STOCK_HANDLE
+ obj
);
490 return (HGDIOBJ16
)(FIRST_STOCK_HANDLE
+ obj
);
494 /***********************************************************************
495 * GetObject16 (GDI.82)
497 INT16 WINAPI
GetObject16( HANDLE16 handle
, INT16 count
, LPVOID buffer
)
501 TRACE("%04x %d %p\n", handle
, count
, buffer
);
502 if (!count
) return 0;
504 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
509 result
= PEN_GetObject16( (PENOBJ
*)ptr
, count
, buffer
);
512 result
= BRUSH_GetObject16( (BRUSHOBJ
*)ptr
, count
, buffer
);
515 result
= BITMAP_GetObject16( (BITMAPOBJ
*)ptr
, count
, buffer
);
518 result
= FONT_GetObject16( (FONTOBJ
*)ptr
, count
, buffer
);
521 * Fix the LOGFONT structure for the stock fonts
523 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
524 (handle
<= LAST_STOCK_HANDLE
) )
525 FixStockFontSize16(handle
, count
, buffer
);
528 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
531 GDI_HEAP_UNLOCK( handle
);
536 /***********************************************************************
537 * GetObjectA (GDI32.204)
539 INT WINAPI
GetObjectA( HANDLE handle
, INT count
, LPVOID buffer
)
543 TRACE("%08x %d %p\n", handle
, count
, buffer
);
544 if (!count
) return 0;
546 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
551 result
= PEN_GetObject( (PENOBJ
*)ptr
, count
, buffer
);
554 result
= BRUSH_GetObject( (BRUSHOBJ
*)ptr
, count
, buffer
);
557 result
= BITMAP_GetObject( (BITMAPOBJ
*)ptr
, count
, buffer
);
560 result
= FONT_GetObjectA( (FONTOBJ
*)ptr
, count
, buffer
);
563 * Fix the LOGFONT structure for the stock fonts
565 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
566 (handle
<= LAST_STOCK_HANDLE
) )
567 FixStockFontSizeA(handle
, count
, buffer
);
570 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
575 case DISABLED_DC_MAGIC
:
578 case METAFILE_DC_MAGIC
:
579 case ENHMETAFILE_MAGIC
:
580 case ENHMETAFILE_DC_MAGIC
:
581 FIXME("Magic %04x not implemented\n",
586 ERR("Invalid GDI Magic %04x\n", ptr
->wMagic
);
589 GDI_HEAP_UNLOCK( handle
);
593 /***********************************************************************
594 * GetObjectW (GDI32.206)
596 INT WINAPI
GetObjectW( HANDLE handle
, INT count
, LPVOID buffer
)
600 TRACE("%08x %d %p\n", handle
, count
, buffer
);
601 if (!count
) return 0;
603 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
608 result
= PEN_GetObject( (PENOBJ
*)ptr
, count
, buffer
);
611 result
= BRUSH_GetObject( (BRUSHOBJ
*)ptr
, count
, buffer
);
614 result
= BITMAP_GetObject( (BITMAPOBJ
*)ptr
, count
, buffer
);
617 result
= FONT_GetObjectW( (FONTOBJ
*)ptr
, count
, buffer
);
620 * Fix the LOGFONT structure for the stock fonts
622 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
623 (handle
<= LAST_STOCK_HANDLE
) )
624 FixStockFontSizeW(handle
, count
, buffer
);
627 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
630 FIXME("Magic %04x not implemented\n",
634 GDI_HEAP_UNLOCK( handle
);
638 /***********************************************************************
639 * GetObjectType (GDI32.205)
641 DWORD WINAPI
GetObjectType( HANDLE handle
)
645 TRACE("%08x\n", handle
);
647 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
676 result
= OBJ_METAFILE
;
678 case METAFILE_DC_MAGIC
:
681 case ENHMETAFILE_MAGIC
:
682 result
= OBJ_ENHMETAFILE
;
684 case ENHMETAFILE_DC_MAGIC
:
685 result
= OBJ_ENHMETADC
;
688 FIXME("Magic %04x not implemented\n",
692 GDI_HEAP_UNLOCK( handle
);
696 /***********************************************************************
697 * GetCurrentObject (GDI32.166)
699 HANDLE WINAPI
GetCurrentObject(HDC hdc
,UINT type
)
701 DC
* dc
= DC_GetDCPtr( hdc
);
706 case OBJ_PEN
: return dc
->w
.hPen
;
707 case OBJ_BRUSH
: return dc
->w
.hBrush
;
708 case OBJ_PAL
: return dc
->w
.hPalette
;
709 case OBJ_FONT
: return dc
->w
.hFont
;
710 case OBJ_BITMAP
: return dc
->w
.hBitmap
;
712 /* the SDK only mentions those above */
713 WARN("(%08x,%d): unknown type.\n",hdc
,type
);
719 /***********************************************************************
720 * SelectObject16 (GDI.45)
722 HGDIOBJ16 WINAPI
SelectObject16( HDC16 hdc
, HGDIOBJ16 handle
)
724 return (HGDIOBJ16
)SelectObject( hdc
, handle
);
728 /***********************************************************************
729 * SelectObject (GDI32.299)
731 HGDIOBJ WINAPI
SelectObject( HDC hdc
, HGDIOBJ handle
)
733 DC
* dc
= DC_GetDCPtr( hdc
);
734 if (!dc
|| !dc
->funcs
->pSelectObject
) return 0;
735 TRACE("hdc=%04x %04x\n", hdc
, handle
);
736 return dc
->funcs
->pSelectObject( dc
, handle
);
740 /***********************************************************************
741 * UnrealizeObject16 (GDI.150)
743 BOOL16 WINAPI
UnrealizeObject16( HGDIOBJ16 obj
)
745 return UnrealizeObject( obj
);
749 /***********************************************************************
750 * UnrealizeObject (GDI32.358)
752 BOOL WINAPI
UnrealizeObject( HGDIOBJ obj
)
755 /* Check if object is valid */
757 GDIOBJHDR
* header
= (GDIOBJHDR
*) GDI_HEAP_LOCK( obj
);
758 if (!header
) return FALSE
;
760 TRACE("%04x\n", obj
);
762 /* Unrealize object */
764 switch(header
->wMagic
)
767 result
= PALETTE_UnrealizeObject( obj
, (PALETTEOBJ
*)header
);
771 /* Windows resets the brush origin. We don't need to. */
774 GDI_HEAP_UNLOCK( obj
);
779 /***********************************************************************
780 * EnumObjects16 (GDI.71)
782 INT16 WINAPI
EnumObjects16( HDC16 hdc
, INT16 nObjType
,
783 GOBJENUMPROC16 lpEnumFunc
, LPARAM lParam
)
785 /* Solid colors to enumerate */
786 static const COLORREF solid_colors
[] =
787 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
788 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
789 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
790 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
791 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
792 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
793 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
794 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
799 LOGBRUSH16
*brush
= NULL
;
801 TRACE("%04x %d %08lx %08lx\n",
802 hdc
, nObjType
, (DWORD
)lpEnumFunc
, lParam
);
806 /* Enumerate solid pens */
807 if (!(pen
= SEGPTR_NEW(LOGPEN16
))) break;
808 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
810 pen
->lopnStyle
= PS_SOLID
;
811 pen
->lopnWidth
.x
= 1;
812 pen
->lopnWidth
.y
= 0;
813 pen
->lopnColor
= solid_colors
[i
];
814 retval
= lpEnumFunc( SEGPTR_GET(pen
), lParam
);
815 TRACE("solid pen %08lx, ret=%d\n",
816 solid_colors
[i
], retval
);
823 /* Enumerate solid brushes */
824 if (!(brush
= SEGPTR_NEW(LOGBRUSH16
))) break;
825 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
827 brush
->lbStyle
= BS_SOLID
;
828 brush
->lbColor
= solid_colors
[i
];
830 retval
= lpEnumFunc( SEGPTR_GET(brush
), lParam
);
831 TRACE("solid brush %08lx, ret=%d\n",
832 solid_colors
[i
], retval
);
836 /* Now enumerate hatched brushes */
837 if (retval
) for (i
= HS_HORIZONTAL
; i
<= HS_DIAGCROSS
; i
++)
839 brush
->lbStyle
= BS_HATCHED
;
840 brush
->lbColor
= RGB(0,0,0);
842 retval
= lpEnumFunc( SEGPTR_GET(brush
), lParam
);
843 TRACE("hatched brush %d, ret=%d\n",
851 WARN("(%d): Invalid type\n", nObjType
);
858 /***********************************************************************
859 * EnumObjects (GDI32.89)
861 INT WINAPI
EnumObjects( HDC hdc
, INT nObjType
,
862 GOBJENUMPROC lpEnumFunc
, LPARAM lParam
)
864 /* Solid colors to enumerate */
865 static const COLORREF solid_colors
[] =
866 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
867 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
868 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
869 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
870 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
871 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
872 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
873 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
880 TRACE("%04x %d %08lx %08lx\n",
881 hdc
, nObjType
, (DWORD
)lpEnumFunc
, lParam
);
885 /* Enumerate solid pens */
886 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
888 pen
.lopnStyle
= PS_SOLID
;
891 pen
.lopnColor
= solid_colors
[i
];
892 retval
= lpEnumFunc( &pen
, lParam
);
893 TRACE("solid pen %08lx, ret=%d\n",
894 solid_colors
[i
], retval
);
900 /* Enumerate solid brushes */
901 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
903 brush
.lbStyle
= BS_SOLID
;
904 brush
.lbColor
= solid_colors
[i
];
906 retval
= lpEnumFunc( &brush
, lParam
);
907 TRACE("solid brush %08lx, ret=%d\n",
908 solid_colors
[i
], retval
);
912 /* Now enumerate hatched brushes */
913 if (retval
) for (i
= HS_HORIZONTAL
; i
<= HS_DIAGCROSS
; i
++)
915 brush
.lbStyle
= BS_HATCHED
;
916 brush
.lbColor
= RGB(0,0,0);
918 retval
= lpEnumFunc( &brush
, lParam
);
919 TRACE("hatched brush %d, ret=%d\n",
926 /* FIXME: implement Win32 types */
927 WARN("(%d): Invalid type\n", nObjType
);
934 /***********************************************************************
935 * IsGDIObject (GDI.462)
937 * returns type of object if valid (W95 system programming secrets p. 264-5)
939 BOOL16 WINAPI
IsGDIObject16( HGDIOBJ16 handle
)
943 if (handle
>= FIRST_STOCK_HANDLE
)
947 case STOCK_WHITE_BRUSH
:
948 case STOCK_LTGRAY_BRUSH
:
949 case STOCK_GRAY_BRUSH
:
950 case STOCK_DKGRAY_BRUSH
:
951 case STOCK_BLACK_BRUSH
:
952 case STOCK_HOLLOW_BRUSH
:
956 case STOCK_WHITE_PEN
:
957 case STOCK_BLACK_PEN
:
958 case STOCK_NULL_PEN
:
962 case STOCK_OEM_FIXED_FONT
:
963 case STOCK_ANSI_FIXED_FONT
:
964 case STOCK_ANSI_VAR_FONT
:
965 case STOCK_SYSTEM_FONT
:
966 case STOCK_DEVICE_DEFAULT_FONT
:
967 case STOCK_SYSTEM_FIXED_FONT
:
968 case STOCK_DEFAULT_GUI_FONT
:
972 case STOCK_DEFAULT_PALETTE
:
973 magic
= PALETTE_MAGIC
;
979 GDIOBJHDR
*object
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
982 magic
= object
->wMagic
;
983 GDI_HEAP_UNLOCK( handle
);
987 if (magic
>= PEN_MAGIC
&& magic
<= METAFILE_DC_MAGIC
)
988 return magic
- PEN_MAGIC
+ 1;
994 /***********************************************************************
995 * SetObjectOwner16 (GDI.461)
997 void WINAPI
SetObjectOwner16( HGDIOBJ16 handle
, HANDLE16 owner
)
1003 /***********************************************************************
1004 * SetObjectOwner (GDI32.386)
1006 void WINAPI
SetObjectOwner( HGDIOBJ handle
, HANDLE owner
)
1011 /***********************************************************************
1012 * MakeObjectPrivate (GDI.463)
1014 void WINAPI
MakeObjectPrivate16( HGDIOBJ16 handle
, BOOL16
private )
1020 /***********************************************************************
1021 * GdiFlush (GDI32.128)
1023 BOOL WINAPI
GdiFlush(void)
1025 return TRUE
; /* FIXME */
1029 /***********************************************************************
1030 * GdiGetBatchLimit (GDI32.129)
1032 DWORD WINAPI
GdiGetBatchLimit(void)
1034 return 1; /* FIXME */
1038 /***********************************************************************
1039 * GdiSetBatchLimit (GDI32.139)
1041 DWORD WINAPI
GdiSetBatchLimit( DWORD limit
)
1043 return 1; /* FIXME */
1047 /***********************************************************************
1048 * GdiSeeGdiDo (GDI.452)
1050 DWORD WINAPI
GdiSeeGdiDo16( WORD wReqType
, WORD wParam1
, WORD wParam2
,
1055 case 0x0001: /* LocalAlloc */
1056 return LOCAL_Alloc( GDI_HeapSel
, wParam1
, wParam3
);
1057 case 0x0002: /* LocalFree */
1058 return LOCAL_Free( GDI_HeapSel
, wParam1
);
1059 case 0x0003: /* LocalCompact */
1060 return LOCAL_Compact( GDI_HeapSel
, wParam3
, 0 );
1061 case 0x0103: /* LocalHeap */
1064 WARN("(wReqType=%04x): Unknown\n", wReqType
);
1069 /***********************************************************************
1070 * GdiSignalProc (GDI.610)
1072 WORD WINAPI
GdiSignalProc( UINT uCode
, DWORD dwThreadOrProcessID
,
1073 DWORD dwFlags
, HMODULE16 hModule
)
1078 /***********************************************************************
1079 * FinalGdiInit16 (GDI.405)
1081 void WINAPI
FinalGdiInit16( HANDLE16 unknown
)
1085 /***********************************************************************
1086 * GdiFreeResources (GDI.609)
1088 WORD WINAPI
GdiFreeResources16( DWORD reserve
)
1090 return (WORD
)( (int)LOCAL_CountFree( GDI_HeapSel
) * 100 /
1091 (int)LOCAL_HeapSize( GDI_HeapSel
) );
1094 /***********************************************************************
1095 * MulDiv16 (GDI.128)
1097 INT16 WINAPI
MulDiv16(
1098 INT16 nMultiplicand
,
1103 if (!nDivisor
) return -32768;
1104 /* We want to deal with a positive divisor to simplify the logic. */
1107 nMultiplicand
= - nMultiplicand
;
1108 nDivisor
= -nDivisor
;
1110 /* If the result is positive, we "add" to round. else,
1111 * we subtract to round. */
1112 if ( ( (nMultiplicand
< 0) && (nMultiplier
< 0) ) ||
1113 ( (nMultiplicand
>= 0) && (nMultiplier
>= 0) ) )
1114 ret
= (((int)nMultiplicand
* nMultiplier
) + (nDivisor
/2)) / nDivisor
;
1116 ret
= (((int)nMultiplicand
* nMultiplier
) - (nDivisor
/2)) / nDivisor
;
1117 if ((ret
> 32767) || (ret
< -32767)) return -32768;
1122 /***********************************************************************
1123 * MulDiv (KERNEL32.391)
1125 * Result of multiplication and division
1126 * -1: Overflow occurred or Divisor was 0
1133 #if SIZEOF_LONG_LONG >= 8
1136 if (!nDivisor
) return -1;
1138 /* We want to deal with a positive divisor to simplify the logic. */
1141 nMultiplicand
= - nMultiplicand
;
1142 nDivisor
= -nDivisor
;
1145 /* If the result is positive, we "add" to round. else, we subtract to round. */
1146 if ( ( (nMultiplicand
< 0) && (nMultiplier
< 0) ) ||
1147 ( (nMultiplicand
>= 0) && (nMultiplier
>= 0) ) )
1148 ret
= (((long long)nMultiplicand
* nMultiplier
) + (nDivisor
/2)) / nDivisor
;
1150 ret
= (((long long)nMultiplicand
* nMultiplier
) - (nDivisor
/2)) / nDivisor
;
1152 if ((ret
> 2147483647) || (ret
< -2147483647)) return -1;
1155 if (!nDivisor
) return -1;
1157 /* We want to deal with a positive divisor to simplify the logic. */
1160 nMultiplicand
= - nMultiplicand
;
1161 nDivisor
= -nDivisor
;
1164 /* If the result is positive, we "add" to round. else, we subtract to round. */
1165 if ( ( (nMultiplicand
< 0) && (nMultiplier
< 0) ) ||
1166 ( (nMultiplicand
>= 0) && (nMultiplier
>= 0) ) )
1167 return ((nMultiplicand
* nMultiplier
) + (nDivisor
/2)) / nDivisor
;
1169 return ((nMultiplicand
* nMultiplier
) - (nDivisor
/2)) / nDivisor
;
1173 /*******************************************************************
1174 * GetColorAdjustment [GDI32.164]
1178 BOOL WINAPI
GetColorAdjustment(HDC hdc
, LPCOLORADJUSTMENT lpca
)
1180 FIXME("GetColorAdjustment, stub\n");
1184 /*******************************************************************
1185 * GetMiterLimit [GDI32.201]
1189 BOOL WINAPI
GetMiterLimit(HDC hdc
, PFLOAT peLimit
)
1191 FIXME("GetMiterLimit, stub\n");
1195 /*******************************************************************
1196 * SetMiterLimit [GDI32.325]
1200 BOOL WINAPI
SetMiterLimit(HDC hdc
, FLOAT eNewLimit
, PFLOAT peOldLimit
)
1202 FIXME("SetMiterLimit, stub\n");
1206 /*******************************************************************
1207 * GdiComment [GDI32.109]
1211 BOOL WINAPI
GdiComment(HDC hdc
, UINT cbSize
, const BYTE
*lpData
)
1213 FIXME("GdiComment, stub\n");
1216 /*******************************************************************
1217 * SetColorAdjustment [GDI32.309]
1221 BOOL WINAPI
SetColorAdjustment(HDC hdc
, const COLORADJUSTMENT
* lpca
)
1223 FIXME("SetColorAdjustment, stub\n");