4 * Copyright 1993 Alexandre Julliard
9 #ifndef X_DISPLAY_MISSING
11 #else /* !defined(X_DISPLAY_MISSING) */
13 #endif /* !defined(X_DISPLAY_MISSING */
26 #include "debugtools.h"
31 DEFAULT_DEBUG_CHANNEL(gdi
)
33 /**********************************************************************/
35 GDI_DRIVER
*GDI_Driver
= NULL
;
37 /***********************************************************************
41 static BRUSHOBJ WhiteBrush
=
43 { 0, BRUSH_MAGIC
, 1 }, /* header */
44 { BS_SOLID
, RGB(255,255,255), 0 } /* logbrush */
47 static BRUSHOBJ LtGrayBrush
=
49 { 0, BRUSH_MAGIC
, 1 }, /* header */
50 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
51 { BS_SOLID
, RGB(192,192,192), 0 } /* logbrush */
54 static BRUSHOBJ GrayBrush
=
56 { 0, BRUSH_MAGIC
, 1 }, /* header */
57 /* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */
58 { BS_SOLID
, RGB(128,128,128), 0 } /* logbrush */
61 static BRUSHOBJ DkGrayBrush
=
63 { 0, BRUSH_MAGIC
, 1 }, /* header */
64 /* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
65 /* NB_HATCH_STYLES is an index into HatchBrushes */
66 { BS_HATCHED
, RGB(0,0,0), NB_HATCH_STYLES
} /* logbrush */
69 static BRUSHOBJ BlackBrush
=
71 { 0, BRUSH_MAGIC
, 1 }, /* header */
72 { BS_SOLID
, RGB(0,0,0), 0 } /* logbrush */
75 static BRUSHOBJ NullBrush
=
77 { 0, BRUSH_MAGIC
, 1 }, /* header */
78 { BS_NULL
, 0, 0 } /* logbrush */
81 static PENOBJ WhitePen
=
83 { 0, PEN_MAGIC
, 1 }, /* header */
84 { PS_SOLID
, { 1, 0 }, RGB(255,255,255) } /* logpen */
87 static PENOBJ BlackPen
=
89 { 0, PEN_MAGIC
, 1 }, /* header */
90 { PS_SOLID
, { 1, 0 }, RGB(0,0,0) } /* logpen */
93 static PENOBJ NullPen
=
95 { 0, PEN_MAGIC
, 1 }, /* header */
96 { PS_NULL
, { 1, 0 }, 0 } /* logpen */
99 static FONTOBJ OEMFixedFont
=
101 { 0, FONT_MAGIC
, 1 }, /* header */
102 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, OEM_CHARSET
,
103 0, 0, DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, "" }
105 /* Filler to make the location counter dword aligned again. This is necessary
106 since (a) FONTOBJ is packed, (b) gcc places initialised variables in the code
107 segment, and (c) Solaris assembler is stupid. */
108 static UINT16 align_OEMFixedFont
= 1;
110 static FONTOBJ AnsiFixedFont
=
112 { 0, FONT_MAGIC
, 1 }, /* header */
113 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
114 0, 0, DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, "" }
116 static UINT16 align_AnsiFixedFont
= 1;
118 static FONTOBJ AnsiVarFont
=
120 { 0, FONT_MAGIC
, 1 }, /* header */
121 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
122 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "MS Sans Serif" }
124 static UINT16 align_AnsiVarFont
= 1;
126 static FONTOBJ SystemFont
=
128 { 0, FONT_MAGIC
, 1 },
129 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
130 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "System" }
132 static UINT16 align_SystemFont
= 1;
134 static FONTOBJ DeviceDefaultFont
=
136 { 0, FONT_MAGIC
, 1 }, /* header */
137 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
138 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "" }
140 static UINT16 align_DeviceDefaultFont
= 1;
142 static FONTOBJ SystemFixedFont
=
144 { 0, FONT_MAGIC
, 1 }, /* header */
145 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
146 0, 0, DEFAULT_QUALITY
, FIXED_PITCH
| FF_MODERN
, "" }
148 static UINT16 align_SystemFixedFont
= 1;
150 /* FIXME: Is this correct? */
151 static FONTOBJ DefaultGuiFont
=
153 { 0, FONT_MAGIC
, 1 }, /* header */
154 { 0, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
155 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, "MS Sans Serif" }
157 static UINT16 align_DefaultGuiFont
= 1;
160 static GDIOBJHDR
* StockObjects
[NB_STOCK_OBJECTS
] =
162 (GDIOBJHDR
*) &WhiteBrush
,
163 (GDIOBJHDR
*) &LtGrayBrush
,
164 (GDIOBJHDR
*) &GrayBrush
,
165 (GDIOBJHDR
*) &DkGrayBrush
,
166 (GDIOBJHDR
*) &BlackBrush
,
167 (GDIOBJHDR
*) &NullBrush
,
168 (GDIOBJHDR
*) &WhitePen
,
169 (GDIOBJHDR
*) &BlackPen
,
170 (GDIOBJHDR
*) &NullPen
,
172 (GDIOBJHDR
*) &OEMFixedFont
,
173 (GDIOBJHDR
*) &AnsiFixedFont
,
174 (GDIOBJHDR
*) &AnsiVarFont
,
175 (GDIOBJHDR
*) &SystemFont
,
176 (GDIOBJHDR
*) &DeviceDefaultFont
,
177 NULL
, /* DEFAULT_PALETTE created by PALETTE_Init */
178 (GDIOBJHDR
*) &SystemFixedFont
,
179 (GDIOBJHDR
*) &DefaultGuiFont
182 HBITMAP hPseudoStockBitmap
; /* 1x1 bitmap for memory DCs */
184 /******************************************************************************
186 * void ReadFontInformation(
187 * char const *fontName,
195 * ReadFontInformation() checks the Wine configuration file's Tweak.Fonts
196 * section for entries containing fontName.Height, fontName.Bold, etc.,
197 * where fontName is the name specified in the call (e.g., "System"). It
198 * attempts to be user friendly by accepting 'n', 'N', 'f', 'F', or '0' as
199 * the first character in the boolean attributes (bold, italic, and
201 *****************************************************************************/
203 static void ReadFontInformation(
204 char const *fontName
,
214 /* In order for the stock fonts to be independent of
215 * mapping mode, the height (& width) must be 0
217 sprintf(key
, "%s.Height", fontName
);
218 font
->logfont
.lfHeight
=
219 PROFILE_GetWineIniInt("Tweak.Fonts", key
, defHeight
);
221 sprintf(key
, "%s.Bold", fontName
);
222 font
->logfont
.lfWeight
=
223 (PROFILE_GetWineIniBool("Tweak.Fonts", key
, defBold
)) ?
226 sprintf(key
, "%s.Italic", fontName
);
227 font
->logfont
.lfItalic
=
228 PROFILE_GetWineIniBool("Tweak.Fonts", key
, defItalic
);
230 sprintf(key
, "%s.Underline", fontName
);
231 font
->logfont
.lfUnderline
=
232 PROFILE_GetWineIniBool("Tweak.Fonts", key
, defUnderline
);
234 sprintf(key
, "%s.StrikeOut", fontName
);
235 font
->logfont
.lfStrikeOut
=
236 PROFILE_GetWineIniBool("Tweak.Fonts", key
, defStrikeOut
);
241 /***********************************************************************
242 * Because the stock fonts have their structure initialized with
243 * a height of 0 to keep them independent of mapping mode, simply
244 * returning the LOGFONT as is will not work correctly.
245 * These "FixStockFontSizeXXX()" methods will get the correct
246 * size for the fonts.
248 static void GetFontMetrics(HFONT handle
, LPTEXTMETRICA lptm
)
253 hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
255 hOldFont
= (HFONT
)SelectObject(hdc
, handle
);
257 GetTextMetricsA(hdc
, lptm
);
259 SelectObject(hdc
, hOldFont
);
264 static inline void FixStockFontSize16(
270 LOGFONT16
* pLogFont
= (LOGFONT16
*)buffer
;
273 * Was the lfHeight field copied (it's the first field)?
274 * If it was and it was null, replace the height.
276 if ( (count
>= 2*sizeof(INT16
)) &&
277 (pLogFont
->lfHeight
== 0) )
279 GetFontMetrics(handle
, &tm
);
281 pLogFont
->lfHeight
= tm
.tmHeight
;
282 pLogFont
->lfWidth
= tm
.tmAveCharWidth
;
286 static inline void FixStockFontSizeA(
292 LOGFONTA
* pLogFont
= (LOGFONTA
*)buffer
;
295 * Was the lfHeight field copied (it's the first field)?
296 * If it was and it was null, replace the height.
298 if ( (count
>= 2*sizeof(INT
)) &&
299 (pLogFont
->lfHeight
== 0) )
301 GetFontMetrics(handle
, &tm
);
303 pLogFont
->lfHeight
= tm
.tmHeight
;
304 pLogFont
->lfWidth
= tm
.tmAveCharWidth
;
309 * Since the LOGFONTA and LOGFONTW structures are identical up to the
310 * lfHeight member (the one of interest in this case) we simply define
311 * the W version as the A version.
313 #define FixStockFontSizeW FixStockFontSizeA
317 /***********************************************************************
320 * GDI initialization.
324 BOOL systemIsBold
= (TWEAK_WineLook
== WIN31_LOOK
);
326 /* Kill some warnings. */
327 (void)align_OEMFixedFont
;
328 (void)align_AnsiFixedFont
;
329 (void)align_AnsiVarFont
;
330 (void)align_SystemFont
;
331 (void)align_DeviceDefaultFont
;
332 (void)align_SystemFixedFont
;
333 (void)align_DefaultGuiFont
;
335 /* TWEAK: Initialize font hints */
336 ReadFontInformation("OEMFixed", &OEMFixedFont
, 0, 0, 0, 0, 0);
337 ReadFontInformation("AnsiFixed", &AnsiFixedFont
, 0, 0, 0, 0, 0);
338 ReadFontInformation("AnsiVar", &AnsiVarFont
, 0, 0, 0, 0, 0);
339 ReadFontInformation("System", &SystemFont
, 0, systemIsBold
, 0, 0, 0);
340 ReadFontInformation("DeviceDefault", &DeviceDefaultFont
, 0, 0, 0, 0, 0);
341 ReadFontInformation("SystemFixed", &SystemFixedFont
, 0, systemIsBold
, 0, 0, 0);
342 ReadFontInformation("DefaultGui", &DefaultGuiFont
, 0, 0, 0, 0, 0);
344 /* Initialize drivers */
346 #ifndef X_DISPLAY_MISSING
347 GDI_Driver
= &X11DRV_GDI_Driver
;
348 #else /* !defined(X_DISPLAY_MISSING) */
349 GDI_Driver
= &TTYDRV_GDI_Driver
;
350 #endif /* !defined(X_DISPLAY_MISSING */
352 GDI_Driver
->pInitialize();
354 /* Create default palette */
356 /* DR well *this* palette can't be moveable (?) */
358 HPALETTE16 hpalette
= PALETTE_Init();
361 StockObjects
[DEFAULT_PALETTE
] = (GDIOBJHDR
*)GDI_HEAP_LOCK( hpalette
);
364 hPseudoStockBitmap
= CreateBitmap( 1, 1, 1, 1, NULL
);
369 /***********************************************************************
372 HGDIOBJ16
GDI_AllocObject( WORD size
, WORD magic
)
374 static DWORD count
= 0;
377 if ( magic
== DC_MAGIC
|| magic
== METAFILE_DC_MAGIC
)
378 handle
= GDI_HEAP_ALLOC( size
);
380 handle
= GDI_HEAP_ALLOC_MOVEABLE( size
);
381 if (!handle
) return 0;
382 obj
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
385 obj
->dwCount
= ++count
;
386 GDI_HEAP_UNLOCK( handle
);
391 /***********************************************************************
394 BOOL
GDI_FreeObject( HGDIOBJ16 handle
)
398 /* Can't free stock objects */
399 if ((handle
>= FIRST_STOCK_HANDLE
) && (handle
<= LAST_STOCK_HANDLE
))
402 object
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
403 if (!object
) return FALSE
;
404 object
->wMagic
= 0; /* Mark it as invalid */
408 GDI_HEAP_FREE( handle
);
412 /***********************************************************************
415 * Return a pointer to the GDI object associated to the handle.
416 * Return NULL if the object has the wrong magic number.
417 * Movable GDI objects are locked in memory: it is up to the caller to unlock
418 * it after the caller is done with the pointer.
420 GDIOBJHDR
* GDI_GetObjPtr( HGDIOBJ16 handle
, WORD magic
)
422 GDIOBJHDR
* ptr
= NULL
;
424 if ((handle
>= FIRST_STOCK_HANDLE
) && (handle
<= LAST_STOCK_HANDLE
))
425 ptr
= StockObjects
[handle
- FIRST_STOCK_HANDLE
];
427 ptr
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
428 if (!ptr
) return NULL
;
429 if ((magic
!= MAGIC_DONTCARE
) && (ptr
->wMagic
!= magic
))
431 GDI_HEAP_UNLOCK( handle
);
438 /***********************************************************************
439 * DeleteObject16 (GDI.69)
441 BOOL16 WINAPI
DeleteObject16( HGDIOBJ16 obj
)
443 return DeleteObject( obj
);
447 /***********************************************************************
448 * DeleteObject32 (GDI32.70)
450 BOOL WINAPI
DeleteObject( HGDIOBJ obj
)
452 /* Check if object is valid */
455 if (HIWORD(obj
)) return FALSE
;
456 if ((obj
>= FIRST_STOCK_HANDLE
) && (obj
<= LAST_STOCK_HANDLE
))
458 if (obj
== hPseudoStockBitmap
) return TRUE
;
459 if (!(header
= (GDIOBJHDR
*) GDI_HEAP_LOCK( obj
))) return FALSE
;
461 TRACE("%04x\n", obj
);
465 switch(header
->wMagic
)
467 case PEN_MAGIC
: return GDI_FreeObject( obj
);
468 case BRUSH_MAGIC
: return BRUSH_DeleteObject( obj
, (BRUSHOBJ
*)header
);
469 case FONT_MAGIC
: return GDI_FreeObject( obj
);
470 case PALETTE_MAGIC
: return PALETTE_DeleteObject(obj
,(PALETTEOBJ
*)header
);
471 case BITMAP_MAGIC
: return BITMAP_DeleteObject( obj
, (BITMAPOBJ
*)header
);
472 case REGION_MAGIC
: return REGION_DeleteObject( obj
, (RGNOBJ
*)header
);
473 case DC_MAGIC
: return DeleteDC(obj
);
475 WARN("Already deleted\n");
478 WARN("Unknown magic number (%d)\n",header
->wMagic
);
483 /***********************************************************************
484 * GetStockObject16 (GDI.87)
486 HGDIOBJ16 WINAPI
GetStockObject16( INT16 obj
)
488 return (HGDIOBJ16
)GetStockObject( obj
);
492 /***********************************************************************
493 * GetStockObject32 (GDI32.220)
495 HGDIOBJ WINAPI
GetStockObject( INT obj
)
497 if ((obj
< 0) || (obj
>= NB_STOCK_OBJECTS
)) return 0;
498 if (!StockObjects
[obj
]) return 0;
499 TRACE("returning %d\n",
500 FIRST_STOCK_HANDLE
+ obj
);
501 return (HGDIOBJ16
)(FIRST_STOCK_HANDLE
+ obj
);
505 /***********************************************************************
506 * GetObject16 (GDI.82)
508 INT16 WINAPI
GetObject16( HANDLE16 handle
, INT16 count
, LPVOID buffer
)
510 GDIOBJHDR
* ptr
= NULL
;
512 TRACE("%04x %d %p\n", handle
, count
, buffer
);
513 if (!count
) return 0;
515 if ((handle
>= FIRST_STOCK_HANDLE
) && (handle
<= LAST_STOCK_HANDLE
))
516 ptr
= StockObjects
[handle
- FIRST_STOCK_HANDLE
];
518 ptr
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
524 result
= PEN_GetObject16( (PENOBJ
*)ptr
, count
, buffer
);
527 result
= BRUSH_GetObject16( (BRUSHOBJ
*)ptr
, count
, buffer
);
530 result
= BITMAP_GetObject16( (BITMAPOBJ
*)ptr
, count
, buffer
);
533 result
= FONT_GetObject16( (FONTOBJ
*)ptr
, count
, buffer
);
536 * Fix the LOGFONT structure for the stock fonts
538 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
539 (handle
<= LAST_STOCK_HANDLE
) )
540 FixStockFontSize16(handle
, count
, buffer
);
543 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
546 GDI_HEAP_UNLOCK( handle
);
551 /***********************************************************************
552 * GetObject32A (GDI32.204)
554 INT WINAPI
GetObjectA( HANDLE handle
, INT count
, LPVOID buffer
)
556 GDIOBJHDR
* ptr
= NULL
;
558 TRACE("%08x %d %p\n", handle
, count
, buffer
);
559 if (!count
) return 0;
561 if ((handle
>= FIRST_STOCK_HANDLE
) && (handle
<= LAST_STOCK_HANDLE
))
562 ptr
= StockObjects
[handle
- FIRST_STOCK_HANDLE
];
564 ptr
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
570 result
= PEN_GetObject( (PENOBJ
*)ptr
, count
, buffer
);
573 result
= BRUSH_GetObject( (BRUSHOBJ
*)ptr
, count
, buffer
);
576 result
= BITMAP_GetObject( (BITMAPOBJ
*)ptr
, count
, buffer
);
579 result
= FONT_GetObjectA( (FONTOBJ
*)ptr
, count
, buffer
);
582 * Fix the LOGFONT structure for the stock fonts
584 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
585 (handle
<= LAST_STOCK_HANDLE
) )
586 FixStockFontSizeA(handle
, count
, buffer
);
589 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
592 FIXME("Magic %04x not implemented\n",
596 GDI_HEAP_UNLOCK( handle
);
599 /***********************************************************************
600 * GetObject32W (GDI32.206)
602 INT WINAPI
GetObjectW( HANDLE handle
, INT count
, LPVOID buffer
)
604 GDIOBJHDR
* ptr
= NULL
;
606 TRACE("%08x %d %p\n", handle
, count
, buffer
);
607 if (!count
) return 0;
609 if ((handle
>= FIRST_STOCK_HANDLE
) && (handle
<= LAST_STOCK_HANDLE
))
610 ptr
= StockObjects
[handle
- FIRST_STOCK_HANDLE
];
612 ptr
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
618 result
= PEN_GetObject( (PENOBJ
*)ptr
, count
, buffer
);
621 result
= BRUSH_GetObject( (BRUSHOBJ
*)ptr
, count
, buffer
);
624 result
= BITMAP_GetObject( (BITMAPOBJ
*)ptr
, count
, buffer
);
627 result
= FONT_GetObjectW( (FONTOBJ
*)ptr
, count
, buffer
);
630 * Fix the LOGFONT structure for the stock fonts
632 if ( (handle
>= FIRST_STOCK_HANDLE
) &&
633 (handle
<= LAST_STOCK_HANDLE
) )
634 FixStockFontSizeW(handle
, count
, buffer
);
637 result
= PALETTE_GetObject( (PALETTEOBJ
*)ptr
, count
, buffer
);
640 FIXME("Magic %04x not implemented\n",
644 GDI_HEAP_UNLOCK( handle
);
648 /***********************************************************************
649 * GetObjectType (GDI32.205)
651 DWORD WINAPI
GetObjectType( HANDLE handle
)
653 GDIOBJHDR
* ptr
= NULL
;
655 TRACE("%08x\n", handle
);
657 if ((handle
>= FIRST_STOCK_HANDLE
) && (handle
<= LAST_STOCK_HANDLE
))
658 ptr
= StockObjects
[handle
- FIRST_STOCK_HANDLE
];
660 ptr
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
690 result
= OBJ_METAFILE
;
692 case METAFILE_DC_MAGIC
:
695 case ENHMETAFILE_MAGIC
:
696 result
= OBJ_ENHMETAFILE
;
698 case ENHMETAFILE_DC_MAGIC
:
699 result
= OBJ_ENHMETADC
;
702 FIXME("Magic %04x not implemented\n",
706 GDI_HEAP_UNLOCK( handle
);
710 /***********************************************************************
711 * GetCurrentObject (GDI32.166)
713 HANDLE WINAPI
GetCurrentObject(HDC hdc
,UINT type
)
715 DC
* dc
= DC_GetDCPtr( hdc
);
720 case OBJ_PEN
: return dc
->w
.hPen
;
721 case OBJ_BRUSH
: return dc
->w
.hBrush
;
722 case OBJ_PAL
: return dc
->w
.hPalette
;
723 case OBJ_FONT
: return dc
->w
.hFont
;
724 case OBJ_BITMAP
: return dc
->w
.hBitmap
;
726 /* the SDK only mentions those above */
727 WARN("(%08x,%d): unknown type.\n",hdc
,type
);
733 /***********************************************************************
734 * SelectObject16 (GDI.45)
736 HGDIOBJ16 WINAPI
SelectObject16( HDC16 hdc
, HGDIOBJ16 handle
)
738 return (HGDIOBJ16
)SelectObject( hdc
, handle
);
742 /***********************************************************************
743 * SelectObject32 (GDI32.299)
745 HGDIOBJ WINAPI
SelectObject( HDC hdc
, HGDIOBJ handle
)
747 DC
* dc
= DC_GetDCPtr( hdc
);
748 if (!dc
|| !dc
->funcs
->pSelectObject
) return 0;
749 TRACE("hdc=%04x %04x\n", hdc
, handle
);
750 return dc
->funcs
->pSelectObject( dc
, handle
);
754 /***********************************************************************
755 * UnrealizeObject16 (GDI.150)
757 BOOL16 WINAPI
UnrealizeObject16( HGDIOBJ16 obj
)
759 return UnrealizeObject( obj
);
763 /***********************************************************************
764 * UnrealizeObject (GDI32.358)
766 BOOL WINAPI
UnrealizeObject( HGDIOBJ obj
)
769 /* Check if object is valid */
771 GDIOBJHDR
* header
= (GDIOBJHDR
*) GDI_HEAP_LOCK( obj
);
772 if (!header
) return FALSE
;
774 TRACE("%04x\n", obj
);
776 /* Unrealize object */
778 switch(header
->wMagic
)
781 result
= PALETTE_UnrealizeObject( obj
, (PALETTEOBJ
*)header
);
785 /* Windows resets the brush origin. We don't need to. */
788 GDI_HEAP_UNLOCK( obj
);
793 /***********************************************************************
794 * EnumObjects16 (GDI.71)
796 INT16 WINAPI
EnumObjects16( HDC16 hdc
, INT16 nObjType
,
797 GOBJENUMPROC16 lpEnumFunc
, LPARAM lParam
)
799 /* Solid colors to enumerate */
800 static const COLORREF solid_colors
[] =
801 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
802 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
803 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
804 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
805 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
806 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
807 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
808 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
813 LOGBRUSH16
*brush
= NULL
;
815 TRACE("%04x %d %08lx %08lx\n",
816 hdc
, nObjType
, (DWORD
)lpEnumFunc
, lParam
);
820 /* Enumerate solid pens */
821 if (!(pen
= SEGPTR_NEW(LOGPEN16
))) break;
822 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
824 pen
->lopnStyle
= PS_SOLID
;
825 pen
->lopnWidth
.x
= 1;
826 pen
->lopnWidth
.y
= 0;
827 pen
->lopnColor
= solid_colors
[i
];
828 retval
= lpEnumFunc( SEGPTR_GET(pen
), lParam
);
829 TRACE("solid pen %08lx, ret=%d\n",
830 solid_colors
[i
], retval
);
837 /* Enumerate solid brushes */
838 if (!(brush
= SEGPTR_NEW(LOGBRUSH16
))) break;
839 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
841 brush
->lbStyle
= BS_SOLID
;
842 brush
->lbColor
= solid_colors
[i
];
844 retval
= lpEnumFunc( SEGPTR_GET(brush
), lParam
);
845 TRACE("solid brush %08lx, ret=%d\n",
846 solid_colors
[i
], retval
);
850 /* Now enumerate hatched brushes */
851 if (retval
) for (i
= HS_HORIZONTAL
; i
<= HS_DIAGCROSS
; i
++)
853 brush
->lbStyle
= BS_HATCHED
;
854 brush
->lbColor
= RGB(0,0,0);
856 retval
= lpEnumFunc( SEGPTR_GET(brush
), lParam
);
857 TRACE("hatched brush %d, ret=%d\n",
865 WARN("(%d): Invalid type\n", nObjType
);
872 /***********************************************************************
873 * EnumObjects32 (GDI32.89)
875 INT WINAPI
EnumObjects( HDC hdc
, INT nObjType
,
876 GOBJENUMPROC lpEnumFunc
, LPARAM lParam
)
878 /* Solid colors to enumerate */
879 static const COLORREF solid_colors
[] =
880 { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff),
881 RGB(0xff,0x00,0x00), RGB(0x00,0xff,0x00),
882 RGB(0x00,0x00,0xff), RGB(0xff,0xff,0x00),
883 RGB(0xff,0x00,0xff), RGB(0x00,0xff,0xff),
884 RGB(0x80,0x00,0x00), RGB(0x00,0x80,0x00),
885 RGB(0x80,0x80,0x00), RGB(0x00,0x00,0x80),
886 RGB(0x80,0x00,0x80), RGB(0x00,0x80,0x80),
887 RGB(0x80,0x80,0x80), RGB(0xc0,0xc0,0xc0)
894 TRACE("%04x %d %08lx %08lx\n",
895 hdc
, nObjType
, (DWORD
)lpEnumFunc
, lParam
);
899 /* Enumerate solid pens */
900 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
902 pen
.lopnStyle
= PS_SOLID
;
905 pen
.lopnColor
= solid_colors
[i
];
906 retval
= lpEnumFunc( &pen
, lParam
);
907 TRACE("solid pen %08lx, ret=%d\n",
908 solid_colors
[i
], retval
);
914 /* Enumerate solid brushes */
915 for (i
= 0; i
< sizeof(solid_colors
)/sizeof(solid_colors
[0]); i
++)
917 brush
.lbStyle
= BS_SOLID
;
918 brush
.lbColor
= solid_colors
[i
];
920 retval
= lpEnumFunc( &brush
, lParam
);
921 TRACE("solid brush %08lx, ret=%d\n",
922 solid_colors
[i
], retval
);
926 /* Now enumerate hatched brushes */
927 if (retval
) for (i
= HS_HORIZONTAL
; i
<= HS_DIAGCROSS
; i
++)
929 brush
.lbStyle
= BS_HATCHED
;
930 brush
.lbColor
= RGB(0,0,0);
932 retval
= lpEnumFunc( &brush
, lParam
);
933 TRACE("hatched brush %d, ret=%d\n",
940 /* FIXME: implement Win32 types */
941 WARN("(%d): Invalid type\n", nObjType
);
948 /***********************************************************************
949 * IsGDIObject (GDI.462)
951 * returns type of object if valid (W95 system programming secrets p. 264-5)
953 BOOL16 WINAPI
IsGDIObject16( HGDIOBJ16 handle
)
957 if (handle
>= FIRST_STOCK_HANDLE
)
961 case STOCK_WHITE_BRUSH
:
962 case STOCK_LTGRAY_BRUSH
:
963 case STOCK_GRAY_BRUSH
:
964 case STOCK_DKGRAY_BRUSH
:
965 case STOCK_BLACK_BRUSH
:
966 case STOCK_HOLLOW_BRUSH
:
970 case STOCK_WHITE_PEN
:
971 case STOCK_BLACK_PEN
:
972 case STOCK_NULL_PEN
:
976 case STOCK_OEM_FIXED_FONT
:
977 case STOCK_ANSI_FIXED_FONT
:
978 case STOCK_ANSI_VAR_FONT
:
979 case STOCK_SYSTEM_FONT
:
980 case STOCK_DEVICE_DEFAULT_FONT
:
981 case STOCK_SYSTEM_FIXED_FONT
:
982 case STOCK_DEFAULT_GUI_FONT
:
986 case STOCK_DEFAULT_PALETTE
:
987 magic
= PALETTE_MAGIC
;
993 GDIOBJHDR
*object
= (GDIOBJHDR
*) GDI_HEAP_LOCK( handle
);
996 magic
= object
->wMagic
;
997 GDI_HEAP_UNLOCK( handle
);
1001 if (magic
>= PEN_MAGIC
&& magic
<= METAFILE_DC_MAGIC
)
1002 return magic
- PEN_MAGIC
+ 1;
1008 /***********************************************************************
1009 * SetObjectOwner16 (GDI.461)
1011 void WINAPI
SetObjectOwner16( HGDIOBJ16 handle
, HANDLE16 owner
)
1017 /***********************************************************************
1018 * SetObjectOwner32 (GDI32.386)
1020 void WINAPI
SetObjectOwner( HGDIOBJ handle
, HANDLE owner
)
1025 /***********************************************************************
1026 * MakeObjectPrivate (GDI.463)
1028 void WINAPI
MakeObjectPrivate16( HGDIOBJ16 handle
, BOOL16
private )
1034 /***********************************************************************
1035 * GdiFlush (GDI32.128)
1037 BOOL WINAPI
GdiFlush(void)
1039 return TRUE
; /* FIXME */
1043 /***********************************************************************
1044 * GdiGetBatchLimit (GDI32.129)
1046 DWORD WINAPI
GdiGetBatchLimit(void)
1048 return 1; /* FIXME */
1052 /***********************************************************************
1053 * GdiSetBatchLimit (GDI32.139)
1055 DWORD WINAPI
GdiSetBatchLimit( DWORD limit
)
1057 return 1; /* FIXME */
1061 /***********************************************************************
1062 * GdiSeeGdiDo (GDI.452)
1064 DWORD WINAPI
GdiSeeGdiDo16( WORD wReqType
, WORD wParam1
, WORD wParam2
,
1069 case 0x0001: /* LocalAlloc */
1070 return LOCAL_Alloc( GDI_HeapSel
, wParam1
, wParam3
);
1071 case 0x0002: /* LocalFree */
1072 return LOCAL_Free( GDI_HeapSel
, wParam1
);
1073 case 0x0003: /* LocalCompact */
1074 return LOCAL_Compact( GDI_HeapSel
, wParam3
, 0 );
1075 case 0x0103: /* LocalHeap */
1078 WARN("(wReqType=%04x): Unknown\n", wReqType
);
1083 /***********************************************************************
1084 * GdiSignalProc (GDI.610)
1086 WORD WINAPI
GdiSignalProc( UINT uCode
, DWORD dwThreadOrProcessID
,
1087 DWORD dwFlags
, HMODULE16 hModule
)
1092 /***********************************************************************
1093 * FinalGdiInit16 (GDI.405)
1095 void WINAPI
FinalGdiInit16( HANDLE16 unknown
)
1099 /***********************************************************************
1100 * GdiFreeResources (GDI.609)
1102 WORD WINAPI
GdiFreeResources16( DWORD reserve
)
1104 return (WORD
)( (int)LOCAL_CountFree( GDI_HeapSel
) * 100 /
1105 (int)LOCAL_HeapSize( GDI_HeapSel
) );
1108 /***********************************************************************
1109 * MulDiv16 (GDI.128)
1111 INT16 WINAPI
MulDiv16( INT16 foo
, INT16 bar
, INT16 baz
)
1114 if (!baz
) return -32768;
1115 ret
= (foo
* bar
) / baz
;
1116 if ((ret
> 32767) || (ret
< -32767)) return -32768;
1121 /***********************************************************************
1122 * MulDiv32 (KERNEL32.391)
1124 * Result of multiplication and division
1125 * -1: Overflow occurred or Divisor was 0
1132 #if SIZEOF_LONG_LONG >= 8
1135 if (!nDivisor
) return -1;
1137 /* We want to deal with a positive divisor to simplify the logic. */
1140 nMultiplicand
= - nMultiplicand
;
1141 nDivisor
= -nDivisor
;
1144 /* If the result is positive, we "add" to round. else, we subtract to round. */
1145 if ( ( (nMultiplicand
< 0) && (nMultiplier
< 0) ) ||
1146 ( (nMultiplicand
>= 0) && (nMultiplier
>= 0) ) )
1147 ret
= (((long long)nMultiplicand
* nMultiplier
) + (nDivisor
/2)) / nDivisor
;
1149 ret
= (((long long)nMultiplicand
* nMultiplier
) - (nDivisor
/2)) / nDivisor
;
1151 if ((ret
> 2147483647) || (ret
< -2147483647)) return -1;
1154 if (!nDivisor
) return -1;
1156 /* We want to deal with a positive divisor to simplify the logic. */
1159 nMultiplicand
= - nMultiplicand
;
1160 nDivisor
= -nDivisor
;
1163 /* If the result is positive, we "add" to round. else, we subtract to round. */
1164 if ( ( (nMultiplicand
< 0) && (nMultiplier
< 0) ) ||
1165 ( (nMultiplicand
>= 0) && (nMultiplier
>= 0) ) )
1166 return ((nMultiplicand
* nMultiplier
) + (nDivisor
/2)) / nDivisor
;
1168 return ((nMultiplicand
* nMultiplier
) - (nDivisor
/2)) / nDivisor
;
1172 /*******************************************************************
1173 * GetColorAdjustment [GDI32.164]
1177 BOOL WINAPI
GetColorAdjustment(HDC hdc
, LPCOLORADJUSTMENT lpca
)
1179 FIXME("GetColorAdjustment, stub\n");
1183 /*******************************************************************
1184 * GetMiterLimit [GDI32.201]
1188 BOOL WINAPI
GetMiterLimit(HDC hdc
, PFLOAT peLimit
)
1190 FIXME("GetMiterLimit, stub\n");
1194 /*******************************************************************
1195 * SetMiterLimit [GDI32.325]
1199 BOOL WINAPI
SetMiterLimit(HDC hdc
, FLOAT eNewLimit
, PFLOAT peOldLimit
)
1201 FIXME("SetMiterLimit, stub\n");
1205 /*******************************************************************
1206 * GdiComment [GDI32.109]
1210 BOOL WINAPI
GdiComment(HDC hdc
, UINT cbSize
, const BYTE
*lpData
)
1212 FIXME("GdiComment, stub\n");
1215 /*******************************************************************
1216 * SetColorAdjustment [GDI32.309]
1220 BOOL WINAPI
SetColorAdjustment(HDC hdc
, const COLORADJUSTMENT
* lpca
)
1222 FIXME("SetColorAdjustment, stub\n");