4 * Copyright 1993 Alexandre Julliard
21 #include "debugtools.h"
27 DEFAULT_DEBUG_CHANNEL(gdi
);
29 /**********************************************************************/
31 GDI_DRIVER
*GDI_Driver
= NULL
;
33 /***********************************************************************
37 static BRUSHOBJ WhiteBrush
=
39 { 0, BRUSH_MAGIC
, 1 }, /* header */
40 { BS_SOLID
, RGB(255,255,255), 0 } /* logbrush */
43 static BRUSHOBJ LtGrayBrush
=
45 { 0, BRUSH_MAGIC
, 1 }, /* header */
46 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
47 { BS_SOLID
, RGB(192,192,192), 0 } /* logbrush */
50 static BRUSHOBJ GrayBrush
=
52 { 0, BRUSH_MAGIC
, 1 }, /* header */
53 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
54 { BS_SOLID
, RGB(128,128,128), 0 } /* logbrush */
57 static BRUSHOBJ DkGrayBrush
=
59 { 0, BRUSH_MAGIC
, 1 }, /* header */
60 /* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
61 /* NB_HATCH_STYLES is an index into HatchBrushes */
62 { BS_HATCHED
, RGB(0,0,0), NB_HATCH_STYLES
} /* logbrush */
65 static BRUSHOBJ BlackBrush
=
67 { 0, BRUSH_MAGIC
, 1 }, /* header */
68 { BS_SOLID
, RGB(0,0,0), 0 } /* logbrush */
71 static BRUSHOBJ NullBrush
=
73 { 0, BRUSH_MAGIC
, 1 }, /* header */
74 { BS_NULL
, 0, 0 } /* logbrush */
77 static PENOBJ WhitePen
=
79 { 0, PEN_MAGIC
, 1 }, /* header */
80 { PS_SOLID
, { 1, 0 }, RGB(255,255,255) } /* logpen */
83 static PENOBJ BlackPen
=
85 { 0, PEN_MAGIC
, 1 }, /* header */
86 { PS_SOLID
, { 1, 0 }, RGB(0,0,0) } /* logpen */
89 static PENOBJ NullPen
=
91 { 0, PEN_MAGIC
, 1 }, /* header */
92 { PS_NULL
, { 1, 0 }, 0 } /* logpen */
95 static FONTOBJ OEMFixedFont
=
97 { 0, FONT_MAGIC
, 1 }, /* header */
98 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, OEM_CHARSET
,
99 0, 0, DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, "" }
101 /* Filler to make the location counter dword aligned again. This is necessary
102 since (a) FONTOBJ is packed, (b) gcc places initialised variables in the code
103 segment, and (c) Solaris assembler is stupid. */
104 static UINT16 align_OEMFixedFont
= 1;
106 static FONTOBJ AnsiFixedFont
=
108 { 0, FONT_MAGIC
, 1 }, /* header */
109 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
110 0, 0, DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, "" }
112 static UINT16 align_AnsiFixedFont
= 1;
114 static FONTOBJ AnsiVarFont
=
116 { 0, FONT_MAGIC
, 1 }, /* header */
117 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
118 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "MS Sans Serif" }
120 static UINT16 align_AnsiVarFont
= 1;
122 static FONTOBJ SystemFont
=
124 { 0, FONT_MAGIC
, 1 },
125 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
126 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "System" }
128 static UINT16 align_SystemFont
= 1;
130 static FONTOBJ DeviceDefaultFont
=
132 { 0, FONT_MAGIC
, 1 }, /* header */
133 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
134 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "" }
136 static UINT16 align_DeviceDefaultFont
= 1;
138 static FONTOBJ SystemFixedFont
=
140 { 0, FONT_MAGIC
, 1 }, /* header */
141 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
142 0, 0, DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, "" }
144 static UINT16 align_SystemFixedFont
= 1;
146 /* FIXME: Is this correct? */
147 static FONTOBJ DefaultGuiFont
=
149 { 0, FONT_MAGIC
, 1 }, /* header */
150 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
151 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "MS Sans Serif" }
153 static UINT16 align_DefaultGuiFont
= 1;
156 static GDIOBJHDR
* StockObjects
[NB_STOCK_OBJECTS
] =
158 (GDIOBJHDR
*) &WhiteBrush
,
159 (GDIOBJHDR
*) &LtGrayBrush
,
160 (GDIOBJHDR
*) &GrayBrush
,
161 (GDIOBJHDR
*) &DkGrayBrush
,
162 (GDIOBJHDR
*) &BlackBrush
,
163 (GDIOBJHDR
*) &NullBrush
,
164 (GDIOBJHDR
*) &WhitePen
,
165 (GDIOBJHDR
*) &BlackPen
,
166 (GDIOBJHDR
*) &NullPen
,
168 (GDIOBJHDR
*) &OEMFixedFont
,
169 (GDIOBJHDR
*) &AnsiFixedFont
,
170 (GDIOBJHDR
*) &AnsiVarFont
,
171 (GDIOBJHDR
*) &SystemFont
,
172 (GDIOBJHDR
*) &DeviceDefaultFont
,
173 NULL
, /* DEFAULT_PALETTE created by PALETTE_Init */
174 (GDIOBJHDR
*) &SystemFixedFont
,
175 (GDIOBJHDR
*) &DefaultGuiFont
178 HBITMAP hPseudoStockBitmap
; /* 1x1 bitmap for memory DCs */
180 /******************************************************************************
182 * void ReadFontInformation(
183 * char const *fontName,
191 * ReadFontInformation() checks the Wine configuration file's Tweak.Fonts
192 * section for entries containing fontName.Height, fontName.Bold, etc.,
193 * where fontName is the name specified in the call (e.g., "System"). It
194 * attempts to be user friendly by accepting 'n', 'N', 'f', 'F', or '0' as
195 * the first character in the boolean attributes (bold, italic, and
197 *****************************************************************************/
199 static void ReadFontInformation(
200 char const *fontName
,
210 /* In order for the stock fonts to be independent of
211 * mapping mode, the height (& width) must be 0
213 sprintf(key
, "%s.Height", fontName
);
214 font
->logfont
.lfHeight
=
215 PROFILE_GetWineIniInt("Tweak.Fonts", key
, defHeight
);
217 sprintf(key
, "%s.Bold", fontName
);
218 font
->logfont
.lfWeight
=
219 (PROFILE_GetWineIniBool("Tweak.Fonts", key
, defBold
)) ?
222 sprintf(key
, "%s.Italic", fontName
);
223 font
->logfont
.lfItalic
=
224 PROFILE_GetWineIniBool("Tweak.Fonts", key
, defItalic
);
226 sprintf(key
, "%s.Underline", fontName
);
227 font
->logfont
.lfUnderline
=
228 PROFILE_GetWineIniBool("Tweak.Fonts", key
, defUnderline
);
230 sprintf(key
, "%s.StrikeOut", fontName
);
231 font
->logfont
.lfStrikeOut
=
232 PROFILE_GetWineIniBool("Tweak.Fonts", key
, defStrikeOut
);
237 /***********************************************************************
238 * Because the stock fonts have their structure initialized with
239 * a height of 0 to keep them independent of mapping mode, simply
240 * returning the LOGFONT as is will not work correctly.
241 * These "FixStockFontSizeXXX()" methods will get the correct
242 * size for the fonts.
244 static void GetFontMetrics(HFONT handle
, LPTEXTMETRICA lptm
)
249 hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
251 hOldFont
= (HFONT
)SelectObject(hdc
, handle
);
253 GetTextMetricsA(hdc
, lptm
);
255 SelectObject(hdc
, hOldFont
);
260 static inline void FixStockFontSize16(
266 LOGFONT16
* pLogFont
= (LOGFONT16
*)buffer
;
269 * Was the lfHeight field copied (it's the first field)?
270 * If it was and it was null, replace the height.
272 if ( (count
>= 2*sizeof(INT16
)) &&
273 (pLogFont
->lfHeight
== 0) )
275 GetFontMetrics(handle
, &tm
);
277 pLogFont
->lfHeight
= tm
.tmHeight
;
278 pLogFont
->lfWidth
= tm
.tmAveCharWidth
;
282 static inline void FixStockFontSizeA(
288 LOGFONTA
* pLogFont
= (LOGFONTA
*)buffer
;
291 * Was the lfHeight field copied (it's the first field)?
292 * If it was and it was null, replace the height.
294 if ( (count
>= 2*sizeof(INT
)) &&
295 (pLogFont
->lfHeight
== 0) )
297 GetFontMetrics(handle
, &tm
);
299 pLogFont
->lfHeight
= tm
.tmHeight
;
300 pLogFont
->lfWidth
= tm
.tmAveCharWidth
;
305 * Since the LOGFONTA and LOGFONTW structures are identical up to the
306 * lfHeight member (the one of interest in this case) we simply define
307 * the W version as the A version.
309 #define FixStockFontSizeW FixStockFontSizeA
313 /***********************************************************************
316 * GDI initialization.
320 BOOL systemIsBold
= (TWEAK_WineLook
== WIN31_LOOK
);
322 /* Kill some warnings. */
323 (void)align_OEMFixedFont
;
324 (void)align_AnsiFixedFont
;
325 (void)align_AnsiVarFont
;
326 (void)align_SystemFont
;
327 (void)align_DeviceDefaultFont
;
328 (void)align_SystemFixedFont
;
329 (void)align_DefaultGuiFont
;
331 /* TWEAK: Initialize font hints */
332 ReadFontInformation("OEMFixed", &OEMFixedFont
, 0, 0, 0, 0, 0);
333 ReadFontInformation("AnsiFixed", &AnsiFixedFont
, 0, 0, 0, 0, 0);
334 ReadFontInformation("AnsiVar", &AnsiVarFont
, 0, 0, 0, 0, 0);
335 ReadFontInformation("System", &SystemFont
, 0, systemIsBold
, 0, 0, 0);
336 ReadFontInformation("DeviceDefault", &DeviceDefaultFont
, 0, 0, 0, 0, 0);
337 ReadFontInformation("SystemFixed", &SystemFixedFont
, 0, systemIsBold
, 0, 0, 0);
338 ReadFontInformation("DefaultGui", &DefaultGuiFont
, 0, 0, 0, 0, 0);
340 /* Create default palette */
342 /* DR well *this* palette can't be moveable (?) */
344 HPALETTE16 hpalette
= PALETTE_Init();
347 StockObjects
[DEFAULT_PALETTE
] = (GDIOBJHDR
*)GDI_HEAP_LOCK( hpalette
);
350 hPseudoStockBitmap
= CreateBitmap( 1, 1, 1, 1, NULL
);
355 /***********************************************************************
358 HGDIOBJ
GDI_AllocObject( WORD size
, WORD magic
)
360 static DWORD count
= 0;
363 if ( magic
== DC_MAGIC
|| magic
== METAFILE_DC_MAGIC
)
364 handle
= GDI_HEAP_ALLOC( size
);
366 handle
= GDI_HEAP_ALLOC_MOVEABLE( size
);
367 if (!handle
) return 0;
368 obj
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
371 obj
->dwCount
= ++count
;
372 GDI_HEAP_UNLOCK( handle
);
377 /***********************************************************************
380 BOOL
GDI_FreeObject( HGDIOBJ handle
)
384 /* Can't free stock objects */
385 if ((handle
>= FIRST_STOCK_HANDLE
) && (handle
<= LAST_STOCK_HANDLE
))
388 object
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
389 if (!object
) return FALSE
;
390 object
->wMagic
= 0; /* Mark it as invalid */
394 GDI_HEAP_FREE( handle
);
398 /***********************************************************************
401 * Return a pointer to the GDI object associated to the handle.
402 * Return NULL if the object has the wrong magic number.
403 * Movable GDI objects are locked in memory: it is up to the caller to unlock
404 * it after the caller is done with the pointer.
406 GDIOBJHDR
* GDI_GetObjPtr( HGDIOBJ handle
, WORD magic
)
408 GDIOBJHDR
* ptr
= NULL
;
410 if (handle
>= FIRST_STOCK_HANDLE
)
412 if (handle
<= LAST_STOCK_HANDLE
) ptr
= StockObjects
[handle
- FIRST_STOCK_HANDLE
];
415 ptr
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
416 if (!ptr
) return NULL
;
417 if ((magic
!= MAGIC_DONTCARE
) && (ptr
->wMagic
!= magic
))
419 GDI_HEAP_UNLOCK( handle
);
426 /***********************************************************************
427 * DeleteObject16 (GDI.69)
429 BOOL16 WINAPI
DeleteObject16( HGDIOBJ16 obj
)
431 return DeleteObject( obj
);
435 /***********************************************************************
436 * DeleteObject (GDI32.70)
438 BOOL WINAPI
DeleteObject( HGDIOBJ obj
)
440 /* Check if object is valid */
443 if (HIWORD(obj
)) return FALSE
;
444 if ((obj
>= FIRST_STOCK_HANDLE
) && (obj
<= LAST_STOCK_HANDLE
))
446 if (obj
== hPseudoStockBitmap
) return TRUE
;
447 if (!(header
= (GDIOBJHDR
*) GDI_HEAP_LOCK( obj
))) return FALSE
;
449 TRACE("%04x\n", obj
);
453 switch(header
->wMagic
)
455 case PEN_MAGIC
: return GDI_FreeObject( obj
);
456 case BRUSH_MAGIC
: return BRUSH_DeleteObject( obj
, (BRUSHOBJ
*)header
);
457 case FONT_MAGIC
: return GDI_FreeObject( obj
);
458 case PALETTE_MAGIC
: return PALETTE_DeleteObject(obj
,(PALETTEOBJ
*)header
);
459 case BITMAP_MAGIC
: return BITMAP_DeleteObject( obj
, (BITMAPOBJ
*)header
);
460 case REGION_MAGIC
: return REGION_DeleteObject( obj
, (RGNOBJ
*)header
);
461 case DC_MAGIC
: return DeleteDC(obj
);
463 WARN("Already deleted\n");
466 WARN("Unknown magic number (%d)\n",header
->wMagic
);
471 /***********************************************************************
472 * GetStockObject16 (GDI.87)
474 HGDIOBJ16 WINAPI
GetStockObject16( INT16 obj
)
476 return (HGDIOBJ16
)GetStockObject( obj
);
480 /***********************************************************************
481 * GetStockObject (GDI32.220)
483 HGDIOBJ WINAPI
GetStockObject( INT obj
)
485 if ((obj
< 0) || (obj
>= NB_STOCK_OBJECTS
)) return 0;
486 if (!StockObjects
[obj
]) return 0;
487 TRACE("returning %d\n",
488 FIRST_STOCK_HANDLE
+ obj
);
489 return (HGDIOBJ16
)(FIRST_STOCK_HANDLE
+ obj
);
493 /***********************************************************************
494 * GetObject16 (GDI.82)
496 INT16 WINAPI
GetObject16( HANDLE16 handle
, INT16 count
, LPVOID buffer
)
500 TRACE("%04x %d %p\n", handle
, count
, buffer
);
501 if (!count
) return 0;
503 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
508 result
= PEN_GetObject16( (PENOBJ
*)ptr
, count
, buffer
);
511 result
= BRUSH_GetObject16( (BRUSHOBJ
*)ptr
, count
, buffer
);
514 result
= BITMAP_GetObject16( (BITMAPOBJ
*)ptr
, count
, buffer
);
517 result
= FONT_GetObject16( (FONTOBJ
*)ptr
, count
, buffer
);
520 * Fix the LOGFONT structure for the stock fonts
522 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
523 (handle
<= LAST_STOCK_HANDLE
) )
524 FixStockFontSize16(handle
, count
, buffer
);
527 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
530 GDI_HEAP_UNLOCK( handle
);
535 /***********************************************************************
536 * GetObjectA (GDI32.204)
538 INT WINAPI
GetObjectA( HANDLE handle
, INT count
, LPVOID buffer
)
542 TRACE("%08x %d %p\n", handle
, count
, buffer
);
543 if (!count
) return 0;
545 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
550 result
= PEN_GetObject( (PENOBJ
*)ptr
, count
, buffer
);
553 result
= BRUSH_GetObject( (BRUSHOBJ
*)ptr
, count
, buffer
);
556 result
= BITMAP_GetObject( (BITMAPOBJ
*)ptr
, count
, buffer
);
559 result
= FONT_GetObjectA( (FONTOBJ
*)ptr
, count
, buffer
);
562 * Fix the LOGFONT structure for the stock fonts
564 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
565 (handle
<= LAST_STOCK_HANDLE
) )
566 FixStockFontSizeA(handle
, count
, buffer
);
569 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
574 case DISABLED_DC_MAGIC
:
577 case METAFILE_DC_MAGIC
:
578 case ENHMETAFILE_MAGIC
:
579 case ENHMETAFILE_DC_MAGIC
:
580 FIXME("Magic %04x not implemented\n",
585 ERR("Invalid GDI Magic %04x\n", ptr
->wMagic
);
588 GDI_HEAP_UNLOCK( handle
);
592 /***********************************************************************
593 * GetObjectW (GDI32.206)
595 INT WINAPI
GetObjectW( HANDLE handle
, INT count
, LPVOID buffer
)
599 TRACE("%08x %d %p\n", handle
, count
, buffer
);
600 if (!count
) return 0;
602 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
607 result
= PEN_GetObject( (PENOBJ
*)ptr
, count
, buffer
);
610 result
= BRUSH_GetObject( (BRUSHOBJ
*)ptr
, count
, buffer
);
613 result
= BITMAP_GetObject( (BITMAPOBJ
*)ptr
, count
, buffer
);
616 result
= FONT_GetObjectW( (FONTOBJ
*)ptr
, count
, buffer
);
619 * Fix the LOGFONT structure for the stock fonts
621 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
622 (handle
<= LAST_STOCK_HANDLE
) )
623 FixStockFontSizeW(handle
, count
, buffer
);
626 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
629 FIXME("Magic %04x not implemented\n",
633 GDI_HEAP_UNLOCK( handle
);
637 /***********************************************************************
638 * GetObjectType (GDI32.205)
640 DWORD WINAPI
GetObjectType( HANDLE handle
)
644 TRACE("%08x\n", handle
);
646 if (!(ptr
= GDI_GetObjPtr( handle
, MAGIC_DONTCARE
))) return 0;
675 result
= OBJ_METAFILE
;
677 case METAFILE_DC_MAGIC
:
680 case ENHMETAFILE_MAGIC
:
681 result
= OBJ_ENHMETAFILE
;
683 case ENHMETAFILE_DC_MAGIC
:
684 result
= OBJ_ENHMETADC
;
687 FIXME("Magic %04x not implemented\n",
691 GDI_HEAP_UNLOCK( handle
);
695 /***********************************************************************
696 * GetCurrentObject (GDI32.166)
698 HANDLE WINAPI
GetCurrentObject(HDC hdc
,UINT type
)
700 DC
* dc
= DC_GetDCPtr( hdc
);
705 case OBJ_PEN
: return dc
->w
.hPen
;
706 case OBJ_BRUSH
: return dc
->w
.hBrush
;
707 case OBJ_PAL
: return dc
->w
.hPalette
;
708 case OBJ_FONT
: return dc
->w
.hFont
;
709 case OBJ_BITMAP
: return dc
->w
.hBitmap
;
711 /* the SDK only mentions those above */
712 WARN("(%08x,%d): unknown type.\n",hdc
,type
);
718 /***********************************************************************
719 * SelectObject16 (GDI.45)
721 HGDIOBJ16 WINAPI
SelectObject16( HDC16 hdc
, HGDIOBJ16 handle
)
723 return (HGDIOBJ16
)SelectObject( hdc
, handle
);
727 /***********************************************************************
728 * SelectObject (GDI32.299)
730 HGDIOBJ WINAPI
SelectObject( HDC hdc
, HGDIOBJ handle
)
732 DC
* dc
= DC_GetDCPtr( hdc
);
733 if (!dc
|| !dc
->funcs
->pSelectObject
) return 0;
734 TRACE("hdc=%04x %04x\n", hdc
, handle
);
735 return dc
->funcs
->pSelectObject( dc
, handle
);
739 /***********************************************************************
740 * UnrealizeObject16 (GDI.150)
742 BOOL16 WINAPI
UnrealizeObject16( HGDIOBJ16 obj
)
744 return UnrealizeObject( obj
);
748 /***********************************************************************
749 * UnrealizeObject (GDI32.358)
751 BOOL WINAPI
UnrealizeObject( HGDIOBJ obj
)
754 /* Check if object is valid */
756 GDIOBJHDR
* header
= (GDIOBJHDR
*) GDI_HEAP_LOCK( obj
);
757 if (!header
) return FALSE
;
759 TRACE("%04x\n", obj
);
761 /* Unrealize object */
763 switch(header
->wMagic
)
766 result
= PALETTE_UnrealizeObject( obj
, (PALETTEOBJ
*)header
);
770 /* Windows resets the brush origin. We don't need to. */
773 GDI_HEAP_UNLOCK( obj
);
778 /***********************************************************************
779 * EnumObjects16 (GDI.71)
781 INT16 WINAPI
EnumObjects16( HDC16 hdc
, INT16 nObjType
,
782 GOBJENUMPROC16 lpEnumFunc
, LPARAM lParam
)
784 /* Solid colors to enumerate */
785 static const COLORREF solid_colors
[] =
786 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
787 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
788 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
789 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
790 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
791 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
792 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
793 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
798 LOGBRUSH16
*brush
= NULL
;
800 TRACE("%04x %d %08lx %08lx\n",
801 hdc
, nObjType
, (DWORD
)lpEnumFunc
, lParam
);
805 /* Enumerate solid pens */
806 if (!(pen
= SEGPTR_NEW(LOGPEN16
))) break;
807 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
809 pen
->lopnStyle
= PS_SOLID
;
810 pen
->lopnWidth
.x
= 1;
811 pen
->lopnWidth
.y
= 0;
812 pen
->lopnColor
= solid_colors
[i
];
813 retval
= lpEnumFunc( SEGPTR_GET(pen
), lParam
);
814 TRACE("solid pen %08lx, ret=%d\n",
815 solid_colors
[i
], retval
);
822 /* Enumerate solid brushes */
823 if (!(brush
= SEGPTR_NEW(LOGBRUSH16
))) break;
824 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
826 brush
->lbStyle
= BS_SOLID
;
827 brush
->lbColor
= solid_colors
[i
];
829 retval
= lpEnumFunc( SEGPTR_GET(brush
), lParam
);
830 TRACE("solid brush %08lx, ret=%d\n",
831 solid_colors
[i
], retval
);
835 /* Now enumerate hatched brushes */
836 if (retval
) for (i
= HS_HORIZONTAL
; i
<= HS_DIAGCROSS
; i
++)
838 brush
->lbStyle
= BS_HATCHED
;
839 brush
->lbColor
= RGB(0,0,0);
841 retval
= lpEnumFunc( SEGPTR_GET(brush
), lParam
);
842 TRACE("hatched brush %d, ret=%d\n",
850 WARN("(%d): Invalid type\n", nObjType
);
857 /***********************************************************************
858 * EnumObjects (GDI32.89)
860 INT WINAPI
EnumObjects( HDC hdc
, INT nObjType
,
861 GOBJENUMPROC lpEnumFunc
, LPARAM lParam
)
863 /* Solid colors to enumerate */
864 static const COLORREF solid_colors
[] =
865 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
866 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
867 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
868 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
869 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
870 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
871 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
872 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
879 TRACE("%04x %d %08lx %08lx\n",
880 hdc
, nObjType
, (DWORD
)lpEnumFunc
, lParam
);
884 /* Enumerate solid pens */
885 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
887 pen
.lopnStyle
= PS_SOLID
;
890 pen
.lopnColor
= solid_colors
[i
];
891 retval
= lpEnumFunc( &pen
, lParam
);
892 TRACE("solid pen %08lx, ret=%d\n",
893 solid_colors
[i
], retval
);
899 /* Enumerate solid brushes */
900 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
902 brush
.lbStyle
= BS_SOLID
;
903 brush
.lbColor
= solid_colors
[i
];
905 retval
= lpEnumFunc( &brush
, lParam
);
906 TRACE("solid brush %08lx, ret=%d\n",
907 solid_colors
[i
], retval
);
911 /* Now enumerate hatched brushes */
912 if (retval
) for (i
= HS_HORIZONTAL
; i
<= HS_DIAGCROSS
; i
++)
914 brush
.lbStyle
= BS_HATCHED
;
915 brush
.lbColor
= RGB(0,0,0);
917 retval
= lpEnumFunc( &brush
, lParam
);
918 TRACE("hatched brush %d, ret=%d\n",
925 /* FIXME: implement Win32 types */
926 WARN("(%d): Invalid type\n", nObjType
);
933 /***********************************************************************
934 * IsGDIObject (GDI.462)
936 * returns type of object if valid (W95 system programming secrets p. 264-5)
938 BOOL16 WINAPI
IsGDIObject16( HGDIOBJ16 handle
)
942 if (handle
>= FIRST_STOCK_HANDLE
)
946 case STOCK_WHITE_BRUSH
:
947 case STOCK_LTGRAY_BRUSH
:
948 case STOCK_GRAY_BRUSH
:
949 case STOCK_DKGRAY_BRUSH
:
950 case STOCK_BLACK_BRUSH
:
951 case STOCK_HOLLOW_BRUSH
:
955 case STOCK_WHITE_PEN
:
956 case STOCK_BLACK_PEN
:
957 case STOCK_NULL_PEN
:
961 case STOCK_OEM_FIXED_FONT
:
962 case STOCK_ANSI_FIXED_FONT
:
963 case STOCK_ANSI_VAR_FONT
:
964 case STOCK_SYSTEM_FONT
:
965 case STOCK_DEVICE_DEFAULT_FONT
:
966 case STOCK_SYSTEM_FIXED_FONT
:
967 case STOCK_DEFAULT_GUI_FONT
:
971 case STOCK_DEFAULT_PALETTE
:
972 magic
= PALETTE_MAGIC
;
978 GDIOBJHDR
*object
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
981 magic
= object
->wMagic
;
982 GDI_HEAP_UNLOCK( handle
);
986 if (magic
>= PEN_MAGIC
&& magic
<= METAFILE_DC_MAGIC
)
987 return magic
- PEN_MAGIC
+ 1;
993 /***********************************************************************
994 * SetObjectOwner16 (GDI.461)
996 void WINAPI
SetObjectOwner16( HGDIOBJ16 handle
, HANDLE16 owner
)
1002 /***********************************************************************
1003 * SetObjectOwner (GDI32.386)
1005 void WINAPI
SetObjectOwner( HGDIOBJ handle
, HANDLE owner
)
1010 /***********************************************************************
1011 * MakeObjectPrivate (GDI.463)
1013 void WINAPI
MakeObjectPrivate16( HGDIOBJ16 handle
, BOOL16
private )
1019 /***********************************************************************
1020 * GdiFlush (GDI32.128)
1022 BOOL WINAPI
GdiFlush(void)
1024 return TRUE
; /* FIXME */
1028 /***********************************************************************
1029 * GdiGetBatchLimit (GDI32.129)
1031 DWORD WINAPI
GdiGetBatchLimit(void)
1033 return 1; /* FIXME */
1037 /***********************************************************************
1038 * GdiSetBatchLimit (GDI32.139)
1040 DWORD WINAPI
GdiSetBatchLimit( DWORD limit
)
1042 return 1; /* FIXME */
1046 /***********************************************************************
1047 * GdiSeeGdiDo (GDI.452)
1049 DWORD WINAPI
GdiSeeGdiDo16( WORD wReqType
, WORD wParam1
, WORD wParam2
,
1054 case 0x0001: /* LocalAlloc */
1055 return LOCAL_Alloc( GDI_HeapSel
, wParam1
, wParam3
);
1056 case 0x0002: /* LocalFree */
1057 return LOCAL_Free( GDI_HeapSel
, wParam1
);
1058 case 0x0003: /* LocalCompact */
1059 return LOCAL_Compact( GDI_HeapSel
, wParam3
, 0 );
1060 case 0x0103: /* LocalHeap */
1063 WARN("(wReqType=%04x): Unknown\n", wReqType
);
1068 /***********************************************************************
1069 * GdiSignalProc (GDI.610)
1071 WORD WINAPI
GdiSignalProc( UINT uCode
, DWORD dwThreadOrProcessID
,
1072 DWORD dwFlags
, HMODULE16 hModule
)
1077 /***********************************************************************
1078 * FinalGdiInit16 (GDI.405)
1080 void WINAPI
FinalGdiInit16( HANDLE16 unknown
)
1084 /***********************************************************************
1085 * GdiFreeResources (GDI.609)
1087 WORD WINAPI
GdiFreeResources16( DWORD reserve
)
1089 return (WORD
)( (int)LOCAL_CountFree( GDI_HeapSel
) * 100 /
1090 (int)LOCAL_HeapSize( GDI_HeapSel
) );
1093 /***********************************************************************
1094 * MulDiv16 (GDI.128)
1096 INT16 WINAPI
MulDiv16(
1097 INT16 nMultiplicand
,
1102 if (!nDivisor
) return -32768;
1103 /* We want to deal with a positive divisor to simplify the logic. */
1106 nMultiplicand
= - nMultiplicand
;
1107 nDivisor
= -nDivisor
;
1109 /* If the result is positive, we "add" to round. else,
1110 * we subtract to round. */
1111 if ( ( (nMultiplicand
< 0) && (nMultiplier
< 0) ) ||
1112 ( (nMultiplicand
>= 0) && (nMultiplier
>= 0) ) )
1113 ret
= (((int)nMultiplicand
* nMultiplier
) + (nDivisor
/2)) / nDivisor
;
1115 ret
= (((int)nMultiplicand
* nMultiplier
) - (nDivisor
/2)) / nDivisor
;
1116 if ((ret
> 32767) || (ret
< -32767)) return -32768;
1121 /*******************************************************************
1122 * GetColorAdjustment [GDI32.164]
1126 BOOL WINAPI
GetColorAdjustment(HDC hdc
, LPCOLORADJUSTMENT lpca
)
1128 FIXME("GetColorAdjustment, stub\n");
1132 /*******************************************************************
1133 * GetMiterLimit [GDI32.201]
1137 BOOL WINAPI
GetMiterLimit(HDC hdc
, PFLOAT peLimit
)
1139 FIXME("GetMiterLimit, stub\n");
1143 /*******************************************************************
1144 * SetMiterLimit [GDI32.325]
1148 BOOL WINAPI
SetMiterLimit(HDC hdc
, FLOAT eNewLimit
, PFLOAT peOldLimit
)
1150 FIXME("SetMiterLimit, stub\n");
1154 /*******************************************************************
1155 * GdiComment [GDI32.109]
1159 BOOL WINAPI
GdiComment(HDC hdc
, UINT cbSize
, const BYTE
*lpData
)
1161 FIXME("GdiComment, stub\n");
1164 /*******************************************************************
1165 * SetColorAdjustment [GDI32.309]
1169 BOOL WINAPI
SetColorAdjustment(HDC hdc
, const COLORADJUSTMENT
* lpca
)
1171 FIXME("SetColorAdjustment, stub\n");